如何让你的图片服务也有类似OSS的图片处理功能

news/2024/11/17 19:19:35/

原文链接

前言

有自己机房的公司一般都有一套存储系统用于存储公司的图片、视频、音频、文件等数据,常见的存储系统有以NAS、FASTDFS为代表的传统文件存储,和以Minio为代表的对象存储系统,随着云服务的兴起很多公司逐渐将数据迁移到以阿里云OSS为代表的云对象存储,OSS的好处是不但解决了数据的存储还自带的很多文件的处理功能,如图片的缩放、打水印、裁剪等功能,例如我们要获获取一张宽为200大小的图片只需要在原图后面增加?x-oss-process=image/resize,w_200这个参数就可以了,处理图片确实非常方便。
https://oss-console-img-demo-cn-hangzhou.oss-cn-hangzhou.aliyuncs.com/example.jpg?x-oss-process=image/resize,w_200。
传统的NAS、FASTDFS只有存储功能,没有文件处理能力的,我们可以使用图片处理软件给它加上类似的图片处理功能。常用的图片处理软件有ImagemagickGraphicsMagickOpenCV对应的JAVA操作库为im4javaJMagickJavacv。用上这些图片处理软件再配置Nginx+Lua或者OpenResty就可以让你的传统NAS存储也也有像OSS一样的图片处理能力。

ImageMagick、GraphicsMagick的安装

ImageMagick官网下载

官网下载地址:https://imagemagick.org/script/download.php
以windows为例,下载ImageMagick-7.1.1-15-Q16-HDRI-x64-dll.exe ,然后下一步、下一步安装就好了,安装完成后输入magick -version检查是否安装成功:

PS C:\Users\Administrator> magick -version
Version: ImageMagick 7.1.1-15 Q16-HDRI x64 a0a5f3d:20230730 https://imagemagick.org
Copyright: (C) 1999 ImageMagick Studio LLC
License: https://imagemagick.org/script/license.php
Features: Cipher DPC HDRI Modules OpenCL OpenMP(2.0)
Delegates (built-in): bzlib cairo flif freetype gslib heic jng jp2 jpeg jxl lcms lqr lzma openexr pangocairo png ps raqm raw rsvg tiff webp xml zip zlib
Compiler: Visual Studio 2022 (193532217)

GraphicsMagick官网下载

GraphicsMagick最初源于ImageMagick5.5.2(2002年11月),但从那时起就完全独立于ImageMagick项目。自从ImageMagick的fork以来,许多作者使用开放的开发模型进行了许多改进(参见新闻),但没有破坏API或实用程序操作。下载地址:
http://www.graphicsmagick.org/download.html
安装完成后输出gm检测是否安装成功。

C:\Users\Administrator>gm
GraphicsMagick 1.3.40 2023-01-14 Q16 http://www.GraphicsMagick.org/
Copyright (C) 2002-2023 GraphicsMagick Group.
Additional copyrights and licenses apply to this software.
See http://www.GraphicsMagick.org/www/Copyright.html for details.
Usage: gm command [options ...]

JAVA操作

JAVA操作GraphicsMagick可以使用im4java
引入POM依赖im4java

        <dependency><groupId>org.im4java</groupId><artifactId>im4java</artifactId><version>1.4.0</version></dependency>

im4java官网地址:
https://im4java.sourceforge.net

im4java源码地址:im4java download | SourceForge.net

JAVA操作ImageMagick可以使用JMagick,引入POM依赖:

<dependency><groupId>jmagick</groupId><artifactId>jmagick</artifactId><version>6.6.9</version>
</dependency>

JMagick官网地址:www.jmagick.org

JMagick源码地址:JMagick download | SourceForge.net

图片信息获取

命令获取图片信息

 magick identify .\1.jpg
.\1.jpg PNG 1920x1080 1920x1080+0+0 8-bit sRGB 1.31707MiB 0.000u 0:00.000//格式化输出
magick identify -format '%W,%H,%B,%f,%m'  .\1.jpg
1920,1080,1381050,1.jpg,PNG

JAVA获取图片信息

    @Testpublic void info() throws IOException, InterruptedException, IM4JavaException {String iImageDir = "C:\\Users\\Administrator\\Desktop\\img\\1.jpg";IMOperation operation = new IMOperation();//格式化输出//operation.format("%W,%H,%B,%f,%m");operation.addImage(iImageDir);IdentifyCmd indentity = new IdentifyCmd();ArrayListOutputConsumer output = new ArrayListOutputConsumer();indentity.setOutputConsumer(output);indentity.run(operation);ArrayList<String> cmdOutput = output.getOutput();String line = cmdOutput.get(0);System.out.println(line);//C:\Users\Administrator\Desktop\img\1.jpg PNG 1920x1080 1920x1080+0+0 8-bit sRGB 1.31707MiB 0.000u 0:00.000}

注意事项

  1. 如果运行代码报org.im4java.core.CommandException: java.io.IOException: Cannot run program "identify": CreateProcess error=2, 系统找不到指定的文件。是因为刚安装软件,系统没找到命令,重启电脑后就可以解决。

  2. 可以使用-format '%W,%H,%B,%f,%m'来格式化图片信息的输出 ,具体的格式化参数有很多,详细可以参考官方文档,你想要的图片信息应该都是有的。https://imagemagick.org/script/escape.phps

图片缩放

命令图片缩放

magick .\1.jpg -resize 200x100 1_w200h100.jpg
magick identify -format '%W,%H,%B,%f,%m'  .\1_w200h100.jpg
输出:
178,100,8003,1_w200h100.jpg,JPEG

JAVA图片缩放

    @Testpublic void resizeImg() throws IOException, InterruptedException, IM4JavaException {String srcImagePath = "C:\\Users\\Administrator\\Desktop\\img\\1.jpg";Integer width = 200;Integer height = 100;String newImagePath = "C:\\Users\\Administrator\\Desktop\\img\\1_w200h100.jpg";IMOperation op = new IMOperation();op.addImage(srcImagePath);op.resize(width, height);op.addImage(newImagePath);ImageCommand convert = new ConvertCmd();convert.run(op);}

注意事项

这里我们使用 -resize 200x100 想生成一张200x100的图片,结果输出图片是178x100,因为原始图片为1920x1080为了保持图片宽高比例,做了等比例缩放,防止图片变形。

图片打水印

命令图片打水印

 magick composite  -geometry  '200x200+100+50'  -gravity  'center'  .\avatar.png .\1.jpg  1_avater.jpg

JAVA图片打水印

    @Testpublic void testaddImgWatermark() throws Exception {String srcImagePath="D://img/1.jpg";String destImagePath="D://img/1_avater.jpg";String waterImgPath="D://img/avatar.png";IMOperation op = new IMOperation();//水印大小op.geometry(1000,1000,1000,500);// 水印图片位置NorthWest, North, NorthEast, West, Center, East, SouthWest, South, SouthEastop.gravity("NorthEast");// 水印透明度op.dissolve(100);// 水印op.addImage(waterImgPath);// 原图op.addImage(srcImagePath);// 目标op.addImage(destImagePath);ImageCommand cmd = new CompositeCmd();cmd.run(op);}

注意事项

  1. -geometry '200x200+100+50' 中的200x200是设置水印图片的大小,+200+50设置水印图片相对于gravity的位置
  2. -gravity 'center'是给定水印的相对原图的位置,支持NorthWest, North, NorthEast, West, Center, East, SouthWest, South, SouthEast,这个参数和阿里OSS加水印的也是一样的。

最终打出水印的效果如下:

image.png

图片裁剪

命令图片裁剪

magick convert -gravity  'center'   .\1_avater.jpg -crop  200x200+100+50 1_cut.jpg

JAVA图片裁剪

    @Testpublic  void testCrop()  throws Exception {String srcImagePath="D://img//1.jpg";String destImagePath="D://img/1_cut.jpg";IMOperation op = new IMOperation();op.gravity("center");op.addImage(srcImagePath);op.crop( 200,200,100,50);op.addImage(destImagePath);ImageCommand cmd  = new ConvertCmd();cmd.run(op, srcImagePath, destImagePath);}

最张裁剪效果:

image.png

注意事项

  1. -crop 200x200+100+50 结合 -gravity 'center'刚好可以把我们打上的水印裁剪出来;
  2. 裁剪出的图片在左右两边还是有一点红色边框,这个可能是计算有一两个像素误差。

图片加参数自动处理

有了以上的图片处理命令之后想要实现OSS ?x-oss-process=image/resize,w_200这样加参数处理图片可以使用Nginx+Lua来实现,集成了Lua模块的Nginx项目OpenResty

例如我们原始图片地址:

http://127.0.0.1/img/1.jpg

自动缩放图片尺寸:

http://127.0.0.1/img/1_400x400.jpg

  1. 下载安装 OpenResty - Download
  2. 下载安装LUA Release Lua for Windows v5.1.5-52 Released · rjpcomputing/luaforwindows · GitHub

Nginx配置引入Lua:

http {lua_package_path 'D:\software\openresty\lualib\\?.lua;;';lua_package_cpath 'D:\software\openresty\lualib\\?.so;;';
}

Nginx配置文件中可以写成这样:

 location ~ '/img/(\d+)_(\d+)x(\d+).jpg$' {root D:/img;set $img_root  "D:/img/img";set $fileName  ngx.arg[1];set $width  ngx.arg[2];set $height  ngx.arg[3];set $origin "${img_root}/${fileName}.jpg" ;set $file  "${img_root}/${fileName}_${width}x${height}.jpg";if (!-f $file) {rewrite_by_lua 'local command = "magick  "..ngx.var.origin.." -resize "..ngx.var.width.."x" ..ngx.var.height.." "..ngx.var.file;os.execute(command);';}}

当访问(http://127.0.0.1/img/1_400x400.jpg时可动态生成对应尺寸图片,类似OSS的功能:

image.png

生成的文件,当然我们还可以使用Lua+Redis缓存这里生成的文件,如果有CDN还可以配置CDN缓存这些文件,下次就可以从CDN缓存直接取对应尺寸的图片了,减少服务器处理图片的性能消耗。很多大厂不将这种图片处理下沉到CDN边缘节点,利用离用户最近CDN节点完成图片数据的处理,减少数据回源,从而减少中心服务器的性能消耗。

image.png

当然这个只是使用Nginx+Lua+GraphicsMagick来实现简单的图片裁剪功能,如果要实现阿里OSS图片处理要比这个复杂的多,不仅要解决大量文件存储高可要和自动扩容问题,还要解决高并发下图片裁剪的性能问题,们只是通过这个案例了解图片自动缩放的基本原理,原理看起来比较简单,想要做的好而且还要给全国那么多企业用,要保持高可用、高性能就比较有难度了。

总结

本文主要介绍了常用图片处理软件ImageMagick的使用,并通过命令和JAVA代码演示图片信息的获取、缩放、打水印、裁剪功能,在最后通过OpenResty+Lua实现类似OSS的自动图片缩放功能。


http://www.ppmy.cn/news/1028528.html

相关文章

Spring5新功能

文章目录 前言一、整合日志功能二、Nullable注解三、函数式风格编程四、JUnit5单元测试框架总结 前言 整合日志、Nullable注解、函数式风格编程、整合JUnit5、Webflux 一、整合日志功能 Spring5移除了Log4jConfigListener&#xff0c;官方建议使用Log4j2. 依赖&#xff1a; &…

【c语言】字符函数与字符串函数(上)

大家好呀&#xff0c;今天给大家分享一下字符函数和字符串函数&#xff0c;说起字符函数和字符串函数大家会想到哪些呢&#xff1f;&#xff1f;我想到的只有求字符串长度的strlen,拷贝字符串的strcpy,字符串比较相同的strcmp,今天&#xff0c;我要分享给大家的是我们一些其他的…

【枚举+推式子】牛客小白月赛 63 E

登录—专业IT笔试面试备考平台_牛客网 题意&#xff1a; 思路&#xff1a; 首先是个计数问题&#xff0c;考虑组合数学 组合数学就是在考虑枚举所有包含1和n的区间 这个典中典就是枚举1和n的位置然后算贡献 双指针超时&#xff0c;考虑推式子&#xff1a; Code&#xff1a…

redis在java中的使用

redis在java中的使用 Redis是一个基于内存的key-value结构数据库&#xff0c;spring data redis是spring的一部分&#xff0c;对redis底层开发包进行了封装&#xff0c;可以直接使用Spring Data Redis简化操作。 5种常见的数据类型 Redis中key是字符串类型&#xff0c;value…

分布式文件存储系统-FastDFS

前言&#xff1a;FastDFS 是一个分布式文件存储系统&#xff0c;主要用于存储和管理大规模的文件数据&#xff0c;如图片、视频、文档等&#xff0c;是淘宝前架构师为了存储图片用C语言开发出来的系统。 服务端有两个组件 Tracker Server 与 Storage Server &#xff0c;对应两…

登录验证码实现

Hutool代码改造 Hutool 有参考文档&#xff1b;很多工具类&#xff1b;把一些功能都封装好&#xff1b;都不用你自己去写&#xff1b;直接调用它的工具类 它这里会详细告诉你引入方式Hutool <dependency><groupId>cn.hutool</groupId><artifactId>hu…

化工行业案例 | 甄知科技助力万华化学重构IT服务价值,打造信息中心ERP!

随着科技的发展&#xff0c;新材料的应用领域与日俱增&#xff0c;近年来&#xff0c;全球化工新材料产业发展整体步入高技术引领、产品迭代速度快、产业规模和需求不断扩大的阶段。一体化协同与数字化转型策略是实现化工新材料生产原料自给、节能降耗、降低排放和物料成本的重…

tomcat服务七层搭建动态页面查看

一个服务器多实例复制完成 配置tomcat多实例的环境变量 vim /etc/profile.d/tomcat.sh配置tomcat1和tomcat2的环境变量 进入tomcat1修改配置 测试通信端口是否正常 连接正常 toncat 2 配置修改 修改这三个 端口配置修改完成 修改tomcat1 shudown 分别把启动文件指向tomcat1…