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

目录

    • 背景
    • 效果图
    • 准备
      • 安装`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.rhkb.cn/news/319506.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

PyVista 3D数据可视化 Python 库 简介 含源码

Pyvista是一个用于科学可视化和分析的Python库 ;我认为它适合做一些网格数据的处理; 它封装了VTK(Visualization Toolkit)之上,提供了一些高级接口, 3D数据可视化变得更加简单和易用。 1.安装 pyvista&…

蓝桥杯-路径之谜

题目描述 小明冒充X星球的骑士,进入了一个奇怪的城堡。城堡里面什么都没有,只有方形石头铺成的地面。 假设城堡的地面时n*n个方格。如下图所示。 按习俗,骑士要从西北角走到东南角。可以横向或者纵向移动,但是不能斜着走&#x…

【设计模式】函数式编程范式工厂模式(Factory Method Pattern)

目录标题 定义函数式接口函数式接口实现类工厂类封装实际应用总结 定义函数式接口 ISellIPad.java /*** 定义一个函数式接口* param <T>*/ FunctionalInterface public interface ISellIPad<T> {T getSellIPadInfo();}函数式接口实现类 HuaWeiSellIPad.java pu…

JAVA系列 小白入门参考资料 接口

目录 接口 接口的概念 语法 接口使用 接口实现用例 接口特性 实现多个接口和实现用例 接口间的继承 接口 接口的概念 在现实生活中&#xff0c;接口的例子比比皆是&#xff0c;比如&#xff1a;笔记本上的 USB 口&#xff0c;电源插座等。 电脑的 USB 口上&am…

初识C语言——第九天

ASCII定义 在 C 语言中&#xff0c;每个字符都对应一个 ASCII 码。ASCII 码是一个字符集&#xff0c;它定义了许多常用的字符对应的数字编码。这些编码可以表示为整数&#xff0c;也可以表示为字符类型。在 C 语言中&#xff0c;字符类型被定义为一个整数类型&#xff0c;它占…

WPF之绑定验证(错误模板使用)

1&#xff0c;前言&#xff1a; 默认情况下&#xff0c;WPF XAML 中使用的绑定并未开启绑定验证&#xff0c;这样导致用户在UI上对绑定的属性进行赋值时即使因不符合规范内部已抛出异常&#xff08;此情况仅限WPF中的数据绑定操作&#xff09;&#xff0c;也被程序默认忽略&…

C#调用skiasharp操作并绘制图片

之前学习ViewFaceCore时采用Panel控件和GDI将图片及识别出的人脸方框和关键点绘制出来&#xff0c;本文将其修改为基于SKControl和SKCanvas实现相同的显示效果并支持保存为本地图片。   新建Winform项目&#xff0c;在Nuget包管理器中搜索并安装一下SkiaSharp和ViewFaceCore…

AD单通道/多通道

1.AD单通道&#xff08;单次转换&#xff0c;非扫描模式&#xff09; 1.1 接线图 1.2 AD.c #include "stm32f10x.h" // Device headervoid AD_Init(void) {RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);//开启GPIOA时钟RCC_APB2PeriphCl…

node.js 解析post请求 方法二

前提&#xff1a;以前面发的node.js解析post请求方法一为模板&#xff0c;具体见 http://t.csdnimg.cn/ABaIn 此文我们运用第二种方法&#xff1a;使用第三方模块formidable对post请求进行解析。 1》代码难点 *** 在Node.js中使用formidable模块来解析POST请求主要涉及到处理…

OpenWRT部署Zerotier虚拟局域网实现内网穿透

前言 细心的小伙伴肯定已经发现了&#xff1a;电脑上部署了Zerotier&#xff0c;如果路由器也部署了OpenWRT&#xff0c;那是否能远程访问呢&#xff1f; 答案是肯定的。 OpenWRT部署Zerotier有啥好处&#xff1f; 那好处必须多&#xff0c;其中的一个便是在外远程控制家里…

初识MVC

初识MVC 理论部分 今天第一次学MVC&#xff0c;拿到一个练手项目。现在来记录一下学习过程。 项目的背景就是个学生管理系统。我只做后端。 从大的来说MVC将应用程序分为三个主要组件&#xff08;部分&#xff09;&#xff1a; 模型&#xff08;Model&#xff09;是应用程序…

sql 中having和where区别

where 是用于筛选表中满足条件的行&#xff0c;不可以和聚类函数一起使用 having 是用于筛选满足条件的组 &#xff0c;可与聚合函数一起使用 所以having语句中不能使用select中定义的名字

Hive大数据任务调度和业务介绍

目录 一、Zookeeper 1.zookeeper介绍 2.数据模型 3.操作使用 4.运行机制 5.一致性 二、Dolphinscheduler 1.Dolphinscheduler介绍 架构 2.架构说明 该服务内主要包含: 该服务包含&#xff1a; 3.FinalShell主虚拟机启动服务 4.Web网页登录 5.使用 5-1 安全中心…

C++中的reverse_iterator迭代器结构设计

目录 reverse_iterator迭代器结构设计 reverse_iterator迭代器基本结构设计 operator*()函数 operator()函数 operator->()函数 operator!()函数 rbegin()函数 rend()函数 operator--()函数 operator()函数 测试代码 const_reverse_iterator迭代器设计 reverse…

安全再升级,亚信安慧AntDB数据库与亚信安全二次牵手完成兼容性互认证

日前&#xff0c;湖南亚信安慧科技有限公司&#xff08;简称&#xff1a;亚信安慧&#xff09;的产品与亚信科技&#xff08;成都&#xff09;有限公司&#xff08;简称&#xff1a;亚信安全&#xff09;再次携手&#xff0c;完成亚信安慧AntDB数据库与亚信安全IPoE接入认证系统…

Ftrans文件外发系统 构建安全可控文件外发流程

文件外发系统是企业数据安全管理中的关键组成部分&#xff0c;它主要用于处理企业内部文件向外部传输的流程&#xff0c;确保数据在合法、安全、可控的前提下进行外发。 文件外发系统的主要作用包括&#xff1a; 1、防止数据泄露&#xff1a;通过严格的审批流程和安全策略&…

节能洗车房车牌识别项目实战

项目背景 学电子信息的你加入了一家节能环保企业&#xff0c;公司的主营产品是节能型洗车房。由于节水节电而且可自动洗车&#xff0c;产品迅速得到了市场和资本的认可。公司决定继续投入研发新一代产品&#xff1a;在节能洗车房的基础上实现无人值守的功能。新产品需要通过图…

Altium Designer——第一课

一个电子设计包含四个部分&#xff1a; 1.原理图库的设计 2.原理图的设计 3.PCB封装库的设计 4.PCB布局和PCB布线的设计 电子设计工程包含的部分&#xff1a; Free documents&#xff1a; 在我们保存AD工程的文件夹中&#xff0c;如果打开的是prjpcb后缀的工程文件&#xf…

《Fundamentals of Power Electronics》——基础交流建模方法

PWM整流器小信号交流模型建模的主要步骤为&#xff1a; (a)利用小纹波近似的动态版本&#xff0c;建立与电感和电容波形的低频平均值有关的方程&#xff1b; (b)平均方程的扰动和线性化&#xff1b; (c)交流等效电路模型的建立。 以下图buck-boost电路为例进行分析。 首先测…

二叉树的迭代遍历 | LeetCode 144. 二叉树的前序遍历、LeetCode 94. 二叉树的中序遍历、LeetCode 145. 二叉树的后序遍历

二叉树的前序遍历&#xff08;迭代法&#xff09; 1、题目 题目链接&#xff1a;144. 二叉树的前序遍历 给你二叉树的根节点 root &#xff0c;返回它节点值的 前序 遍历。 示例 1&#xff1a; 输入&#xff1a;root [1,null,2,3] 输出&#xff1a;[1,2,3]示例 2&#x…