Java环境下Imagemagick中文图片处理问题非完美解决方案
2009-12-30 09:49
519 查看
Java环境下Imagemagick中文图片处理问题非完美解决方案
Posted 四月 9, 2009Comments(0)
在处理服务器与客户端交互时候,基于性能考虑(参考手机客户端网络加速技术方案实现思考
),
对软件介绍中的图片采用缩略图进行展现,这样涉及了实际图片缩略图的动态处理问题,采用Java的Runtime.getRuntime().exec直
接来调用Imagemagick的命令来完成缩略图的动态生成。原本是一个很简单的问题,只不过由于在图片的目录路径及图片名称中存在中文,因此在处理时
候又出现了FileNotFoundException,记录一下非完美解决方案。
1、系统环境:
操作系统:Red Hat Enterprise Linux AS release 4 (Nahant Update 4)操作系统用户环境变量(参考Linux环境下资源下载中文目录及中文文件名称问题
):
export LC_ALL=zh_CN.GB18030
export LANG= zh_CN.GB18030
JVM、Tomcat、数据库等相关的字符集(参考Struts2中Datetimepicker控件的中文问题
):UTF-8
2、需求场景
手机客户端对于图片的请求分为两大类:图片的下载请求、图片的预览请求。图片的下载请求
:客户端请求下载实际的图片内容,此时候服务器端不需要对图片进行任何加工处理,只需要正确返回实际的图片内容。
图片的预览请求
:客户端并不需要下载完整的图片内容,只需要在客户端能够预览图片,因此在分辨率及图片质量上可以稍稍降低,以节省带宽资源。在手机客户端发起图片预览请求时候,服务器端响应的所有的图片都采用缩略图(降低图片大小)及低分辨率(降低图片质量)的方式返回。
备注:通过手机浏览器或手机客户端下载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/sh
cat /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/sh
iconv -f UTF-8 -t GBK -c /home/client.aouu.com/img/img1.txt -o /home/client.aouu.com/img/img2.txt
cat /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
,中文目录
,中文文件名
,中文乱码
相关文章推荐
- Java环境下Imagemagick中文图片处理问题非完美解决方案
- Java环境下Imagemagick中文图片处理问题非完美解决方案
- Java压缩解压zip文件的中文文件名在Windows和Linux环境下乱码问题的解决方案
- Java技术平台中文处理问题分析及解决方案
- java中 使用ImageMagick处理图片(对图片处理要求比较高的解决方案)
- Java文件名包含中文的文件压缩后文件名乱码问题,完美解决方案
- Java文件名包含中文的文件压缩后文件名乱码问题,完美解决方案
- Java 图片处理解决方案:ImageMagick 快速入门教程
- Mysql中文乱码问题完美解决方案
- Java线程之锁对象Lock-同步问题更完美的处理方式代码实例
- Mysql中文乱码问题完美解决方案
- 解决方案:mysql的中文问题(开发语言:Java)
- Java线程(八):锁对象Lock-同步问题更完美的处理方式
- Mysql中文乱码问题完美解决方案
- JAVA/J2ME中文编码问题完全解决方案
- Mysql中文乱码问题完美解决方案[转]
- JAVA中如何处理中文的全角和半角问题- -
- 转载:Java 关于中文乱码问题的解决方案与经验
- Mysql中文乱码问题完美解决方案
- JAVA 页面传值 get方式提交 中文乱码问题的解决方案