centos7 openresty lua 自适应webp和缩放图片

news/2024/5/17 11:58:15

目录

    • 背景
    • 效果图
    • 准备
      • 安装`cwebp`等命令,转换文件格式
      • 安装`ImageMagick`,压缩文件
      • 下载Lua API 操控ImageMagick的依赖包
    • 代码
    • 参考

背景

  • 缩小图片体积,提升加载速度,节省流量。

效果图

  • 参数格式 : ?image_process=format,webp/resize,p_20
    在这里插入图片描述

在这里插入图片描述

准备

安装cwebp等命令,转换文件格式

yum install  libwebp-devel libwebp-tools

安装ImageMagick,压缩文件

yum install  ImageMagick

下载Lua API 操控ImageMagick的依赖包

  • 网址:https://github.com/leafo/magick,到Releases下载,解压后得到如下:
    在这里插入图片描述
  • 复制magick包到lualib里,如下所示。
    在这里插入图片描述

代码

  • 修改conf文件,添加如下内容。
      location ~ \.(jpe?g|png|gif)$ {add_header Access-Control-Allow-Origin *;add_header Access-Control-Allow-Methods 'GET, POST, OPTIONS';add_header Access-Control-Allow-Headers 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization';content_by_lua_file /usr/local/openresty/nginx/conf/lua/image-convert.lua;}
  • 创建/usr/local/openresty/nginx/conf/lua/image-convert.lua 文件。添加一下内容。
local originalFile = ngx.var.request_filenamelocal image_process = ngx.var.arg_image_process
-- local image_process = ngx.req.get_uri_args()["image_process"]function fileExists(name)local f=io.open(name,"r")if f~=nil then io.close(f) return true else return false end
endfunction tryServeFile(name, contentType)if fileExists(name) thenlocal f = io.open(name, "rb")local content = f:read("*all")f:close()if contentType ~= "" thenngx.header["Content-Type"] = contentTypeendngx.print(content)return trueendreturn false
endfunction serveFileOr404(name, contentType)if not tryServeFile(name, contentType) thenngx.exit(404)end
endfunction ratioZip(originalFile,ratioFile) if not fileExists(ratioFile) thenlocal ratio_num = string.match(image_process, "%d+")local magick = require("magick")local img = assert(magick.load_image(originalFile))local r_num = tonumber(ratio_num) / 100local w = img:get_width() * r_numlocal h = img:get_height() * r_numimg:destroy()local size_str = tostring(math.floor(w)) .. "x" .. tostring(math.floor(h))magick.thumb(originalFile, size_str , ratioFile)endendfunction outputWebp(originalFile,commandExe)local newFile = originalFile .. ".converted.webp"local headers = ngx.req.get_headers()if headers ~= nil and headers["accept"] ~= nil and string.find(headers["accept"], "image/webp") ~= nil thenif not tryServeFile(newFile, "image/webp") thenos.execute(commandExe .. " -q 80 " .. originalFile .. " -o " .. newFile);serveFileOr404(originalFile, "image/webp")endelseif image_process ~= nil and string.find(image_process, "webp") ~= nil thenif not tryServeFile(newFile, "image/webp") thenos.execute(commandExe .. " -q 80 " .. originalFile .. " -o " .. newFile);serveFileOr404(originalFile, "image/webp")endelseserveFileOr404(originalFile, "")endendfunction zipAndWebp(originalFile,commandExe)--ngx.header["Content-Type"] = "text/html; charset=UTF-8"--ngx.say("imgp ",image_process,string.find(image_process, "resize")," 比例 ",number)local ratio_num = nilif image_process ~= nil and string.find(image_process, "resize") ~= nil thenratio_num = string.match(image_process, "%d+")end-- ngx.say("imgp ",ratio_num)-- 是否要压缩if  ratio_num ~= nil and tonumber(ratio_num) > 0 thenlocal ratioFile = originalFile .. ratio_numratioZip(originalFile,ratioFile) outputWebp(ratioFile,commandExe)elseoutputWebp(originalFile,commandExe)endendif string.find(originalFile, ".png") ~= nil thenzipAndWebp(originalFile,"cwebp")
elseif string.find(originalFile, ".jpg") ~= nil thenzipAndWebp(originalFile,"cwebp")
elseif string.find(originalFile, ".jpeg") ~= nil thenzipAndWebp(originalFile,"cwebp")
elseif string.find(originalFile, ".gif") ~= nil thenoutputWebp(originalFile,"gif2webp")
else serveFileOr404(originalFile, "")
end
  • 参数格式
?image_process=format,webp/resize,p_20

参考

  • https://blog.rexskz.info/use-openresty-to-optimize-image-size-with-avif-and-webp.html
  • https://blog.csdn.net/F_angT/article/details/90073211
  • https://www.jianshu.com/p/b14c89b57493

http://www.mrgr.cn/p/08703325

相关文章

短视频素材哪个App最好?短视频素材哪里有免费的?

在数字媒体的黄金时代,富有创意的视频内容已成为吸引观众的关键。高质量的视频素材不仅能增强视觉效果,还能提升整体叙述的力度。以下列出了一系列全球顶尖的视频素材提供网站,它们将为你的广告制作、社交媒体或任何视频项目提供极具影响力的…

Java安全基础之Java反射机制和ClassLoader类加载机制

反射机制允许程序在运行时检查和操作类、对象、方法以及属性的信息。类加载机制负责将类的字节码加载到内存中,并且在运行时动态地链接和初始化类。目录Java 反射机制反射 java.lang.RuntimeClassLoader 类加载机制URLClassLoaderloadClass() 与 Class.forName() 的区别? Jav…

高中生一定就会了么???(i)

\(题源:2023星光杯数学思维能力测评(小学组)第一试\)\(表示离谱\)

打破失联困境:门店如何利用AI智能名片B2B2C商城小程序重构与消费者的紧密连接?

在如今这个消费者行为日益碎片化的时代,门店经营者们时常感叹:消费者进店如同一场不期而遇的缘分,然而一旦离开门店,就仿佛消失在茫茫人海中,难以再觅其踪迹。这种“进店靠缘分,离店就失联”的困境&#xf…

鸿蒙安装apk软件失败(不支持该设备)

1.关闭纯净模式增强模块 2.给文件管理器一个权限,一个安装外部来源应用的权限魔芋爽要犯了.jpg1.关闭纯净血压增高模块 2.安装外部来源(默认文件管理器是没有权限的) 3.没登华为账号,等七天过了再来试试后续(matepad11.5就是垃圾,快退!.jpg)

Outlook大附件插件 有效解决附件大小限制问题

很多企业都是使用Outlook来进行邮件的收发,可是由于附件大小有限,导致很多大文件发不出去,就会产生Outlook大附件插件这种业务需求。 邮件系统在发送大文件时面临的限制问题主要如下: 1、附件大小限制:大多数邮件服务…

1. SpringBoot 入门

1. SpringBoot 简介 SpringBoot是由Pivotal团队提供的全新框架,可以帮助我们开发基于Spring的、独立的、生产级的应用程序。​ 其中SpringBoot的官网是:Spring Boot Reference DocumentationSpringBoot的主要目标是:为所有Spring开发提供更快的入门体验开箱即用,提供了自动…

uniapp视频播放器(h5+app)

关于uniapp视频播放器遇到的一些问题,mark下。 中途遇到了很多问题,如果有相同的伙伴遇到了类似的,欢迎交流 官方的video播放器在app上不友好,有以下功能不支持。 loadedmetadata、controlstoggle不支持导致只能手写控制层。 不…

mysql连接不上,服务中找不到mysql

分析 因为太久没使用mysql,服务自动删除了解决 注册/安装服务 win+x,a,以管理员打开powershell(或者使用cmd,随你) # 注意此处需要引号,因为有空格 # 1. cd到mysql的可执行文件,如果记不得或者像我一样懒,直接everything搜索mysqld.exe即可 cd C:\Program Files\MySQL\My…

星趴解包教程

目录#1 提取资源文件#2 解密#3 读取资源#4 导出资源#4.1 导出单个 / 少量资源#4.2 按种类导出资源#5 资源去重(可选) 本篇文章偏小白向,有一定基础的可以选择性阅读 本文仅供学习交流使用,请勿用于商业用途。更新至 2024.5.2, 星趴版本号 v1.2.3_20240430_123a#1 提取资源文…

快速了解Django:核心概念解析与实践指南

title: 快速了解Django:核心概念解析与实践指南 date: 2024/5/1 20:31:41 updated: 2024/5/1 20:31:41 categories: 后端开发 tags: Django核心路由系统视图系统ORM管理中间件Web框架登录装饰器 第一章:Django简介 背景和发展历程: Djan…

站立会议和燃尽图10

站立会议和燃尽图10 一、小组情况 组长:李宏威 组员:董泽豪 队名:隐约雷名 二、Scrum例会 时间:2024年4月29日 出席人员:李宏威,董泽豪 要求1 工作照片要求2 时间跨度 2024年4月29日 7:00 至 2024年4月29日 7:20 共计 20 分钟 要求3 地点 石家庄铁道大学 要求4 立会内容包…

【深耕 Python】Data Science with Python 数据科学(17)Scikit-learn机器学习(二)

写在前面 关于数据科学环境的建立,可以参考我的博客: 【深耕 Python】Data Science with Python 数据科学(1)环境搭建 往期数据科学博文一览: 【深耕 Python】Data Science with Python 数据科学(2&…

站立会议和燃尽图09

站立会议和燃尽图09 一、小组情况 组长:李宏威 组员:董泽豪 队名:隐约雷名 二、Scrum例会 时间:2024年4月21日 出席人员:李宏威,董泽豪 要求1 工作照片要求2 时间跨度 2024年4月28日 7:00 至 2024年4月28日 7:20 共计 20 分钟 要求3 地点 石家庄铁道大学 要求4 立会内容包…

vulnhub靶场之FunBox-1

一.环境搭建 1.靶场描述 Boot2Root ! This is a reallife szenario, but easy going. You have to enumerate and understand the szenario to get the root-flag in round about 20min. This VM is created/tested with Virtualbox. Maybe it works with vmware. If you n…

重定义大语言模型的记忆能力:对抗性压缩如何挑战现有测量法

DeepVisionary 每日深度学习前沿科技推送&顶会论文分享,与你一起了解前沿深度学习信息! Rethinking LLM Memorization through the Lens of Adversarial Compression 引言:探索大型语言模型的记忆能力 在当今信息时代,大型…

Elasticsearch:理解近似最近邻 (ANN) 算法

作者:来自 Elastic Elastic Platform Team 如果你是在互联网出现之前长大的,你会记得找到新喜好并不总是那么容易。我们是在无意中听到收音机里的新乐队时发现他们的,是因为忘了换频道偶然看到一个新电视节目的,也是几乎完全依据游…

jsrpc获取瑞数请求后缀和cookie

jsrpc获取瑞数请求后缀和cookie 记得加入我们的学习群:961566389 点击链接加入群聊:https://h5.qun.qq.com/s/62P0xwrCNO 1.分析xhr 每次请求都能看到会携带一个请求后缀uB04BPdr:以及每次请求都会更换cookie下的mEsoE3ffu2LGP:这两个就是需要逆向的参数。 2.调试 因为使用j…

spring boot3单模块项目工程搭建-下(个人开发模板)

⛰️个人主页: 蒾酒 🔥系列专栏:《spring boot实战》 目录 写在前面 上文衔接 常用依赖介绍以及整合 web组件 测试组件 样板代码生成 数据库连接器 常用工具包 面向切面编程 ORM框架 数据连接池 接口测试、文档导出 缓存中间件 参数校…