Java环境下Imagemagick中文图片处理问题非完美解决方案

Java环境下Imagemagick中文图片处理问题非完美解决方案 Posted 四月 9, 2009 Comments(1) 在处理服务器与客户端交互时候,基于性能考虑(参考手机客户端网络加速技术方案实现思考),对软件介绍中的图片采用缩略图进行展现,这样涉及了实际图片缩略图的动态处理问题,采用Java的Runtime.getRuntime().exec直接来调用Imagemagick的命令来完成缩略图的动态生成。原本是一个很简单的问题,只不过由于在图片的目录路径及图片名称中存在中文,因此在处理时候又出现了FileNotFoundException,记录一下非完美解决方案。1、系统环境:操作系统:Red Hat Enterprise Linux AS release 4 (Nahant Update 4)操作系统用户环境变量(参考Linux环境下资源下载中文目录及中文文件名称问题):export LC_ALL=zh_CN.GB18030export LANG= zh_CN.GB18030JVM、Tomcat、数据库等相关的字符集(参考Struts2中Datetimepicker控件的中文问题):UTF-82、需求场景 手机客户端对于图片的请求分为两大类:图片的下载请求、图片的预览请求。图片的下载请求:客户端请求下载实际的图片内容,此时候服务器端不需要对图片进行任何加工处理,只需要正确返回实际的图片内容。图片的预览请求:客户端并不需要下载完整的图片内容,只需要在客户端能够预览图片,因此在分辨率及图片质量上可以稍稍降低,以节省带宽资源。在手机客户端发起图片预览请求时候,服务器端响应的所有的图片都采用缩略图(降低图片大小)及低分辨率(降低图片质量)的方式返回。备注:通过手机浏览器或手机客户端下载1M左右以上的资源时候,如果采用Struts2的Stream Result,存在服务器端无响应的现象,具体原因没有查明,有空看看Struts2代码再说,采用传统的response写流的方式实现没有此问题。3、实现机制采用Runtime.getRuntime().exec(“/usr/bin/convert -sample 75%x75% /test.jpg /test_thumb.jpg”)来动态生成缩略图。备注:a、考虑到jmagick并不能完整支持Imagemagick所有命令集且使用上并不是很方便,因此没有采用jmagick,直接使用Runtime.getRuntime().exec(“/usr/bin/convert -sample 75%x75% /test.jpg /test_thumb.jpg”)的方案,使用方法具体可以参考在线主题制作技术实现方案 b、这里使用的imagemagick的命令只供测试使用,不一定是最佳的命令,具体查一下imagemagick的手册c、由于Imagemagick生成图片相对较慢,因此并不需要每一次都生成缩略图,可以将缩略图存放在与原有图片相同的目录路径下,这样在客户端发起图片预览请求时候,服务器端先查看一下请求图片的预览图是否存在,如果存在直接返回以前生成的预览图,如果不存在则动态生成后再返回。4、问题在使用Runtime.getRuntime().exec调用convert来动态生成缩略图时候,由于资源在Linux服务器上存放目录及文件名称都存在中文(例如/products/material/img/101×80 /人物肖像101×8/测试.jpg),因此在调用时候会报FileNotFoundException错误。5、方案测试测试命令:/usr/bin/convert -sample 75%x75% /img/101×80/人物肖像101×8/测试.jpg /img/101×80/人物肖像101×8/测试_thumb.jpg试验1:操作:操作系统编码为zh_CN.GB18030,因此在shell命令行执行convert,如果传入的字符串参数为正常的zh_CN.GBK(比zh_CN.GB18030范围小)的编码,那么不会乱码。结果:在命令行执行,已验证。试验2:操作:JVM环境变量为UTF-8,Java内部本身也是采用UTF-8编码,Runtime.getRuntime().exec调用convert时候,如果将参数进行转码成zh_CN.GBK,则应该能够正常处理private static final String CMD=”/usr/bin/convert “;private static final String PRAM=” -sample 75%x75% “;…inputPath=new String(inputPath.getBytes(“UTF-8″),”GBK”);outPutPath=new String(outPutPath.getBytes(“UTF-8″),”GBK”);Process pc=Runtime.getRuntime().exec(CMD+PRAM+inputPath+” “+outPutPath);结果:以上代码不行,将getBytes的编码换成GBK、ISO8859-1,输出编码换成UTF-8、ISO8859-1等也一样试验3:操作:将JVM环境变量修改为GBK结果:似乎也不行试验4:操作:在java代码中,将中文路径/img/101×80/人物肖像101×8/测试.jpg /img/101×80/人物肖像101×8/测试_thumb.jpg写入普通文本文件/home/client.aouu.com/img/img2.txt,然后在命令行调用convert来生成Java代码(示例,不规范):FileWriter os = new FileWriter(“/home/client.aouu.com/img/img1.txt”);String imgPath=inputPath+” “+outPutPath;os.write(imgPath);os.close();Process pc=Runtime.getRuntime().exec(“/home/client.aouu.com/img/img.sh”);pc.waitFor();img.sh:#!/bin/shcat /home/client.aouu.com/img/img1.txt |xargs /usr/bin/convert -sample 75%x75%结果:不行,报告-bash: ./img.sh: cannot execute binary file试验5:操作:与试验4操作相同img.sh:#!/bin/shiconv -f UTF-8 -t GBK -c /home/client.aouu.com/img/img1.txt -o /home/client.aouu.com/img/img2.txtcat /home/client.aouu.com/img/img2.txt |xargs /usr/bin/convert -sample 75%x75%结果:OK结果分析:尽管在java代码中将中文路径、中文文件名称的编码转码成GBK,但java内部本身是UTF-8编码,因此JVM通过Runtime.getRuntime().exec传给/usr/bin/convert的参数实际上仍然为UTF-8编码(?是什么编码,尚待验证),并不是GBK编码,因此convert获取输入参数后无法在操作系统找到对应的文件。通过FileWriter写入文件的字符集也为UTF-8,通过iconv强制将UTF-8编码转化为GBK,这样convert能够正常处理。具体的原因及机理尚待进一步考察验证,现在尚无好的办法,姑且凑合使用此种方案再说。Technorati 标签: linux,中文目录,中文文件名,中文乱码,环境变量,java,imagemagick,convert,iconv站内标签:convert,环境变量,iconv,imagemagick,java,linux,中文目录,中文文件名,中文乱码 1 Comment so far Java图像压缩优化 - J2EE企业应用 顾问/咨询- H.E.'s Blog on 二月 26th, 2010 [...] 参考地址: ImageMagick中文网站 Java环境下Imagemagick中文图片处理问题非完美解决方案 [...]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值