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_filename
 

local 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
end

function tryServeFile(name, contentType)
    if fileExists(name) then
        local f = io.open(name, "rb")
        local content = f:read("*all")
        f:close()
        if contentType ~= "" then
            ngx.header["Content-Type"] = contentType
        end
        ngx.print(content)
        return true
    end
    return false
end

function serveFileOr404(name, contentType)
    if not tryServeFile(name, contentType) then
        ngx.exit(404)
    end
end


function ratioZip(originalFile,ratioFile) 
	if not fileExists(ratioFile) then
		local ratio_num = string.match(image_process, "%d+")
		local magick = require("magick")
		local img = assert(magick.load_image(originalFile))
		local r_num = tonumber(ratio_num) / 100
		local w = img:get_width() * r_num
		local h = img:get_height() * r_num
		img:destroy()
		
		local size_str = tostring(math.floor(w)) .. "x" .. tostring(math.floor(h))
		magick.thumb(originalFile, size_str , ratioFile)
	end
		

end

function 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 then
		if not tryServeFile(newFile, "image/webp") then
			 os.execute(commandExe .. " -q 80 " .. originalFile .. " -o " .. newFile);
			 serveFileOr404(originalFile, "image/webp")
		end
	elseif image_process ~= nil and string.find(image_process, "webp") ~= nil then
		if not tryServeFile(newFile, "image/webp") then
			 os.execute(commandExe .. " -q 80 " .. originalFile .. " -o " .. newFile);
			 serveFileOr404(originalFile, "image/webp")
		end
	else
		serveFileOr404(originalFile, "")
	end

end

function 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 = nil
    if image_process ~= nil and string.find(image_process, "resize") ~= nil then
		ratio_num = string.match(image_process, "%d+")
    end
   
	-- ngx.say("imgp ",ratio_num)
	 
	-- 是否要压缩
	if  ratio_num ~= nil and tonumber(ratio_num) > 0 then
		local ratioFile = originalFile .. ratio_num
		ratioZip(originalFile,ratioFile) 
		outputWebp(ratioFile,commandExe)
	else
		outputWebp(originalFile,commandExe)
	end
	
	
	
	
end

 
if string.find(originalFile, ".png") ~= nil then
   
   zipAndWebp(originalFile,"cwebp")
elseif string.find(originalFile, ".jpg") ~= nil then
	 zipAndWebp(originalFile,"cwebp")
elseif string.find(originalFile, ".jpeg") ~= nil then
	 zipAndWebp(originalFile,"cwebp")
elseif string.find(originalFile, ".gif") ~= nil then
	 outputWebp(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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/582091.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

在IDEA中使用.env文件导入系统配置的图文教程

JetBrains的IDEA是一款功能强大的集成开发环境,为开发人员提供了丰富的功能和工具。使用.env文件来管理配置信息在IDEA中非常简单。 旧版本默认支持,新版本idea需要安装插件才可以。 这里我们可以安装EnvFile插件,步骤如下: 在弹…

centos 7 安装 JDK 和Rockmq

1、版本说明 CentOS版本:使用 cat /etc/redhat-release 命令查看centos版本。 本次版本是:CentOS Linux release 7.9.2009 (Core) JDK版本是:jdk-8u401-linux-x64.tar.gz RockeqMQ版本:rocketmq-all-4.9.2-bin-release.zip …

Vue 组件单元测试深度探索:细致解析与实战范例大全

Vue.js作为一款广受欢迎的前端框架,以其声明式的数据绑定、组件化开发和灵活的生态系统赢得了广大开发者的心。然而,随着项目规模的增长,确保组件的稳定性和可靠性变得愈发关键。单元测试作为软件质量的守护神,为Vue组件的开发过程…

人脸识别系统架构

目录 1. 系统架构 1.1 采集子系统 1.2 解析子系统 1.3 存储子系统 1.4 比对子系统 1.5 决策子系统 1.6 管理子系统 1.7 应用开放接口 2. 业务流程 2.1 人脸注册 2.2 人脸验证 2.2.1 作用 2.2.2 特点 2.2.3 应用场景 2.3 人脸辨识 2.3.1 作用 2.3.2 特点 2.3.3…

学习STM32第二十天

低功耗编程 一、修改主频 STM32F4xx系列主频为168MHz,当板载8MHz晶振时,系统时钟HCLK满足公式 H C L K H S E P L L N P L L M P L L P HCLK \frac{HSE \times PLLN}{PLLM \times PLLP} HCLKPLLMPLLPHSEPLLN​,在文件stm32f4xx.h中可修…

HTML 学习笔记

html 超文本标记语言(英语:HyperText Markup Language,简称:HTML)是一种用于创建网页的标准标记语言。 1.HTML文档的后缀名 (1) .html (2) .htm 这里更推荐使用 ".html ",命名应该遵从含义清…

FPGA 以太网概念简单学习

1 MAC和PHY 从硬件的角度来说,以太网接口电路主要由 MAC ( Media Access Control )控制器和物理层接口 PHY(Physical Layer , PHY )两大部分构成。 MAC 指媒体访问控制子层协议,它和 PHY 接…

SpringMVC进阶(自定义拦截器以及异常处理)

文章目录 1.自定义拦截器1.基本介绍1.说明2.自定义拦截器的三个方法3.流程图 2.快速入门1.Myinterceptor01.java2.FurnHandler.java3.springDispatcherServlet-servlet.xml配置拦截器4.单元测试 3.拦截特定路径1.拦截指定路径2.通配符配置路径 4.细节说明5.多个拦截器1.执行流程…

刷代码随想录有感(49):找树左下角的值

题干&#xff1a; 用层序遍历方便些&#xff0c;因为只需要把res不断替换成每一层第一个节点值即可&#xff0c;代码如下&#xff1a; class Solution { public:int findBottomLeftValue(TreeNode* root) {queue<TreeNode*>que;if(root ! NULL)que.push(root);int res …

逆向案例三十——webpack登录某游戏

网址&#xff1a;aHR0cHM6Ly93d3cuZ205OS5jb20v 步骤&#xff1a; 进行抓包分析&#xff0c;找到登录接口&#xff0c;发现密码有加密 跟栈分析&#xff0c;从第三个栈进入&#xff0c;打上断点&#xff0c;再次点击登录 明显找到password,它由o赋值&#xff0c;o由a.encode(…

【哈希】Leetcode 面试题 01.02. 判定是否互为字符重排

题目讲解 面试题 01.02. 判定是否互为字符重排 算法讲解 直观的想法&#xff1a;我们找到一个字符串的全排列&#xff0c;然后对比当前的排列是否等于另一个字符串。如果两个字符串如果互为排列&#xff0c;所以我们知道两个字符串对应的字符出现的个数相同&#xff0c;那么…

在config.json文件中配置出来new mars3d.graphic.PolylineCombine({大量线合并渲染类型的geojson图层

在config.json文件中配置出来new mars3d.graphic.PolylineCombine({大量线合并渲染类型的geojson图层 问题场景&#xff1a; 1.浏览官网示例的时候图层看到大量线数据合并渲染的示例 2.矢量数据较大量级的时候&#xff0c;这种时候怎么在config.json文件中尝试配置呢&#x…

高并发内存池: 介绍

一.功能介绍 功能: 用于实现高效的多线程内存管理(替代系统的内存分配相关的函数(malloc, free)) 性能的提升: 池化技术, 锁竞争的减小处理内存碎片: 内碎片, 外碎片 池化技术: 概念:预先向系统申请过量的资源, 自己管理.->提高性能(每次申请资源都有较大的开销, 提前申…

数字文旅重塑旅游发展新生态:以数字化转型为契机,推动旅游产业的创新发展,提升旅游服务的智能化、网络化和个性化水平

目录 一、引言 二、数字化转型推动旅游产业创新发展 1、数字化转型提升旅游产业效率 2、数字化转型拓展旅游产业边界 3、数字化转型促进旅游产业可持续发展 三、提升旅游服务智能化、网络化和个性化水平 1、智能化提升旅游服务体验 2、网络化拓宽旅游服务渠道 3、个性…

OpenHarmony实战开发-多层级手势事件

多层级手势事件指父子组件嵌套时&#xff0c;父子组件均绑定了手势或事件。在该场景下&#xff0c;手势或者事件的响应受到多个因素的影响&#xff0c;相互之间发生传递和竞争&#xff0c;容易出现预期外的响应。 本章主要介绍了多层级手势事件的默认响应顺序&#xff0c;以及…

【大学生电子竞赛题目分析】——2023年H题《信号分离装置》

今年的大赛已临近落幕&#xff0c;笔者打算陆续对几个熟悉领域的题目作一番分析与讨论&#xff0c;今天首先分析H题。 网上有一些关于H题的分析&#xff0c;许多都是针对盲信号分析的。然而本题具有明确的信号频率范围&#xff0c;明确的信号可能频率&#xff0c;明确的信号波…

全栈从0到1 3D旅游地图标记和轨迹生成

功能演示 演示视频 体验地址 Vercel App 开发技术栈&#xff1a; NextJs&#xff08;前端框架&#xff09;React&#xff08;前端框架&#xff09;TailwindCSS &#xff08;CSS样式&#xff09;echart echart gl &#xff08;地图生成&#xff09;shadui&#xff08;UI组件…

HTML5本地存储账号密码

<!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>HTML5本地存储账号密码</title> </head…

[论文笔记]SEARCHING FOR ACTIVATION FUNCTIONS

引言 今天带来另一篇激活函数论文SEARCHING FOR ACTIVATION FUNCTIONS的笔记。 作者利用自动搜索技术来发现新的激活函数。通过结合详尽的搜索和基于强化学习的搜索&#xff0c;通过实验发现最佳的激活函数 f ( x ) x ⋅ sigmoid ( β x ) f(x) x \cdot \text{sigmoid}(βx…

Android 学习 鸿蒙HarmonyOS 4.0 第二天(项目结构认识)

项目结构认识 和 了解&#xff1a; 工程目录下的结构如下&#xff1a; 首先能看到有两个.开头的文件&#xff0c;分别是.hvigor 和 .idea。这两个文件夹都是与构建有关系的&#xff0c; 如果你开发过安卓app&#xff0c;构建完会生成一个apk安装包&#xff0c;鸿蒙则是生成hap…