GraphicsMagick+im4java实现高质量大图的处理

本文介绍如何安装GraphicsMagick并使用im4java库在Java中实现高质量的大图处理,包括裁剪、缩放及添加水印等功能,解决了处理大文件及高分辨率图片时的内存溢出问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

下载 .tar.gz 的源码包,进行解压

tar -xvzf GraphicsMagick-1.3.12.tar.gz

解压后,原来在的gz文件就变成了tar文件,进入文件夹

cd GraphicsMagick-1.3.12

安装之前,因为是图片处理,所以需要系统中安装了libpng和libjpeg的开发包,否则的话不会安装这两种文件的支持。

使用 configure 来进行自动的配置、build和安装

./configure

当然,可以通过 –prefix=PATH 来指定参数,还可以指定其他编译时的变量,这里使用了一个经过测试的 configure 配置,同时添加了 enable-sybol-prefix ,这样就避免了和系统中已有的 ImageMagick 的冲突,下面是完成的配置参数:

./configure  '--build=i686-redhat-linux-gnu' '--host=i686-redhat-linux-gnu' '--target=i386-redhat-linux-gnu' '--program-prefix=' '--prefix=/usr/local/sinasrv2' '--exec-prefix=/usr/local/sinasrv2' '--bindir=/usr/local/sinasrv2/bin' '--sbindir=/usr/local/sinasrv2/sbin' '--sysconfdir=/usr/local/sinasrv2/etc' '--datadir=/usr/local/sinasrv2/share' '--includedir=/usr/local/sinasrv2/include' '--libdir=/usr/local/sinasrv2/lib' '--libexecdir=/usr/local/sinasrv2/libexec' '--localstatedir=/usr/local/sinasrv2/var' '--sharedstatedir=/usr/local/sinasrv2/share/com' '--mandir=/usr/local/sinasrv2/share/man' '--infodir=/usr/local/sinasrv2/share/info' '--enable-libtool-verbose' '--with-included-ltdl' '--enable-shared' '--disable-static' '--with-modules' '--with-frozenpaths' '--without-perl' '--without-magick-plus-plus' '--with-quantum-depth=8' --enable-symbol-prefix

接下来就是安装

make

make install

 

程序中代码:

001 package imageUtils; 002 003 import java.io.IOException; 004 import java.util.ArrayList; 005 006 import org.im4java.core.ConvertCmd; 007 import org.im4java.core.IMOperation; 008 009 /** 010 * @author hegh E-mail: heguanhua@tjhq.com 011 * @version 创建时间:Mar 13, 2012 10:43:12 AM 类说明 012 */ 013 public class ImageMagick { 014 015 /** * ImageMagick的路径 */ 016 publicstatic String imageMagickPath =null; 017 static{/**获取ImageMagick的路径 */ 018 //Properties prop = new PropertiesFile().getPropertiesFile(); 019 //linux下不要设置此值,不然会报错 020 //imageMagickPath = prop.getProperty("imageMagickPath"); 021 } 022 023 /** * 根据坐标裁剪图片 024 * @param srcPath 要裁剪图片的路径 025 * @param newPath 裁剪图片后的路径 026 * @param x 起始横坐标 027 * @param y 起始挫坐标 028 * @param x1 结束横坐标 029 * @param y1 结束挫坐标 030 */ 031 publicstatic void cutImage(String srcPath, String newPath, intx, int y, int x1, int y1) 032 throwsException { 033 intwidth = x1 - x; intheight = y1 - y; 034 IMOperation op =new IMOperation(); 035 op.addImage(srcPath); 036 /** 037 * width:裁剪的宽度 038 * height:裁剪的高度 039 * x:裁剪的横坐标 040 * y:裁剪的挫坐标 041 */ 042 op.crop(width, height, x, y); 043 op.addImage(newPath); 044 ConvertCmd convert =new ConvertCmd(); 045 //linux下不要设置此值,不然会报错 046 //convert.setSearchPath(imageMagickPath); 047 convert.run(op); 048 } 049 050 /** 051 * 根据尺寸缩放图片 052 * @param width 缩放后的图片宽度 053 * @param height 缩放后的图片高度 054 * @param srcPath 源图片路径 055 * @param newPath 缩放后图片的路径 056 * @param type 1为比例处理,2为大小处理,如(比例:1024x1024,大小:50%x50%) 057 */ 058 publicstatic String cutImage(intwidth, int height, String srcPath, String newPath,inttype,String quality) throwsException { 059 IMOperation op =new IMOperation(); 060 ConvertCmd cmd =new ConvertCmd(true); 061 op.addImage(); 062 String raw =""; 063 if(type ==1){ 064 //按像素 065 raw = width+"x"+height+"^"; 066 }else{ 067 //按像素百分比 068 raw = width+"%x"+height+"%"; 069 } 070 op.addRawArgs("-sample", raw ); 071 if((quality !=null&& quality.equals(""))){ 072 op.addRawArgs("-quality", quality ); 073 } 074 op.addImage(); 075 076 String osName = System.getProperty("os.name").toLowerCase(); 077 if(osName.indexOf("win") != -1) { 078 //linux下不要设置此值,不然会报错 079 cmd.setSearchPath("C://Program Files//GraphicsMagick-1.3.14-Q16"); 080 } 081 082 try{ 083 cmd.run(op, srcPath, newPath); 084 }catch(Exception e){ 085 e.printStackTrace(); 086 } 087 returnnewPath; 088 } 089 090 091 /** 092 * 给图片加水印 093 * @param srcPath 源图片路径 094 */ 095 publicstatic void addImgText(String srcPath) throws Exception { 096 IMOperation op =new IMOperation(); 097 op.font("宋体").gravity("southeast").pointsize(18).fill("#BCBFC8").draw("text 100,100 co188.com"); 098 op.addImage(); 099 op.addImage(); 100 101 String osName = System.getProperty("os.name").toLowerCase(); 102 ConvertCmd cmd =new ConvertCmd(true); 103 if(osName.indexOf("win") != -1) { 104 //linux下不要设置此值,不然会报错 105 cmd.setSearchPath("C://Program Files//GraphicsMagick-1.3.14-Q16"); 106 } 107 108 try{ 109 cmd.run(op, srcPath, srcPath); 110 }catch(Exception e){ 111 e.printStackTrace(); 112 } 113 } 114 115 publicstatic void main(String[] args) throws Exception{ 116 //cutImage("D:\\apple870.jpg", "D:\\apple870eee.jpg",98, 48, 370, 320); 117 Long start = System.currentTimeMillis(); 118 //cutImage(100,100, "e:\\37AF7D10F2D8448A9A5.jpg","e:\\37AF7D10F2D8448A9A5_bak2.jpg",2,"100"); 119 addImgText("e:\\37AF7D10F2D8448A9A5_bak2.jpg"); 120 Long end = System.currentTimeMillis(); 121 System.out.println("time:"+(end-start)/3600); 122 } 123 } 124 通过GraphicsMagick+im4java实现高质量大图的处理,解决了100M以上,以及图片像素10000以上处理是出现内存溢出的问


 

### GraphicsMagick 中文水印乱码的原因分析 GraphicsMagick 是从 ImageMagick 分离出来的图像处理库,虽然它继承了许多功能,但在某些高级特性上仍存在不足。其中一个重要问题是,GraphicsMagick 对于复杂字符集的支持不够完善,尤其是对于中文等非拉丁字符集的处理能力较弱[^1]。 当尝试在图片上添加中文水印时,由于字体编码不匹配或缺少必要的中文字体支持,可能会导致乱码现象。这种问题的根本原因在于 GraphicsMagick 的内部实现并未全面覆盖复杂的字体渲染需求。 --- ### 解决方案一:指定正确的字体文件 可以通过设置 `-font` 参数来加载特定的中文字体文件,从而解决乱码问题。以下是具体方法: #### Python 实现示例 ```python from wand.image import Image as WandImage from wand.drawing import Drawing from wand.font import Font with Drawing() as draw: with WandImage(width=800, height=600, background='white') as img: font_path = '/path/to/some/chinese/font.ttf' # 替换为实际的中文字体路径 text = '你好,世界' draw.font = font_path draw.fill_color = 'black' draw.text(50, 50, text) draw(img) img.save(filename='/output/path/image_with_watermark.png') ``` 通过显式指定中文字体文件(如 `simhei.ttf` 或其他支持中文的 TTF 字体),可以有效避免乱码问题[^3]。 --- ### 解决方案二:切换至 ImageMagick 如果 GraphicsMagick 的功能无法满足需求,可以选择使用完整的 ImageMagick 库。相比于 GraphicsMagickImageMagick 提供更强大的字体支持和更高的兼容性。为了确保 Node.js 脚本能够正确调用 ImageMagick,需执行以下操作: 1. **卸载现有工具** 首先彻底移除已安装的 GraphicsMagickImageMagick 工具。 2. **单独安装 ImageMagick** 下载并安装最新版本的 ImageMagick,并将其路径配置到环境变量中。 3. **修改 gm 模块路径** 使用 Node.js 的 `gm` 模块时,可通过参数明确指向 ImageMagick 的可执行文件位置: ```javascript const gm = require('gm').subClass({ imageMagick: true }); ``` 这样即可绕开 GraphicsMagick 的局限性,利用 ImageMagick 完成高质量的中文水印生成任务[^1]。 --- ### 解决方案三:基于 IM4JavaJava 后端实现 对于后端开发场景,推荐采用 IM4Java 结合 ImageMagick 来完成中文水印功能。IM4Java 是一个轻量级的 Java 接口层,用于封装命令行形式的 ImageMagick 命令。其主要优势在于跨平台性和灵活性。 #### Java 示例代码 ```java import org.im4java.core.IMOperation; import org.im4java.core.ConvertCmd; import org.im4java.core.ImageCommand; public class WatermarkExample { public static void main(String[] args) throws Exception { IMOperation op = new IMOperation(); op.addImage("input.jpg"); op.font("/path/to/some/chinese/font.ttf"); // 设置中文字体 op.fill("#FF0000"); // 文字颜色 (红色) op.draw("text 10,10 '你好'"); op.addImage("output.jpg"); ConvertCmd convert = new ConvertCmd(); convert.run(op); } } ``` 此方式不仅解决了中文乱码问题,还提供了丰富的自定义选项,适合企业级应用场景[^2]。 --- ### 总结 针对 GraphicsMagick 中文水印乱码的问题,有三种可行的解决方案: 1. 显式指定中文字体文件; 2. 切换至功能更强的 ImageMagick; 3. 在后端环境中引入 IM4Java 并配合 ImageMagick 使用。 每种方案各有优劣,可根据项目实际情况灵活选择。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

天下琴川

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值