ImageMagick & JMagick的使用-高品质高效率缩略图的解决方案
Pure java的图片操作,不依赖操作系统的功能,图片运算量比较大,如果批处理图片或图片size较大的话(如1M左右的图片)的话,性能肯定不能满足;用JNI(java本地调用),依赖操作系统提供的功能, 操作批量、大图片,就成为首选方案。
我在winxp环境下安装调试JMagick,并成功运行了测试code,实现了图片的多种操作,缩略图、旋转、设置边框、设置背景等等...,下面记录安装及配置历史,分享给大家:
ImageMagick, JMagick安装、配置及使用:
平台:winXP?
1.?安装ImageMagick(ImageMagick website:http://www.imagemagick.org/script/index.php)
??? 下载并安装ImageMagick。file name: ImageMagick-6.2.6-8-Q16-windows-dll.exe
???? download address:?http://prdownloads.sourceforge.net/imagemagick/ImageMagick-6.2.6-8-Q16-windows-dll.exe?download
??? 安装成功后,
把install path加入系统path(有些版本自己会默认添加),以便能调用dll.保险起见,
然后再把安装目录下的所有dll文件复制到C:\WINDOWS\system32下(因为我出现过只添加路径而不复制这些文件到C:\WINDOWS\system32,程序运行提示出错的情况)
2.?安装JMagick(JMagick website:?http://www.yeo.id.au/jmagick/)
??? 下载JMatick。file name: jmagick-6.2.6-win.zip?
??? download address:?http://www.yeo.id.au/jmagick/quickload/win-6.2.6/jmagick-6.2.6-win.zip
??? 解压后
把jmagick-6.2.6-win\q16\jmagick.dll copy 到c:\windows\system32目录下,如果程序在运行的时候提示:找不到jmagick路径,用System.out.println(System.getProperty("java.library.path")).?打印出当前环境的路径,然后再把jmagick.dll 复制到其中的一个路径文件夹中
?
notes:?If you are using Tomcat, or other java applications which have their own classloaders,
方法1: 把jmagick-6.2.6-win\jar\jmagick.jar copy到项目的WEB-INF\lib目录下,然后在服务启动初始化的时候,System.setProperty("jmagick.systemclassloader","no");?? (可以在过滤器的那个类里面加上这句话,也可以自己手动建立一个初始化的serverlet,然后加上这句话)
方法2:简单的方法,把jmagick-6.2.6-win\jar\jmagick.jar 复制到%JAVA_HOME%\jre\lib\ext.就ok了
?
下面总结下windows + tomcat环境的安装配置
1:下载安装ImageMagick-6.3.4-10-Q16-windows-dll.exe
2:把install path加入系统path,然后把install path下的dll文件复制到C:\WINDOWS\system32
3:下载JMatick。file name:jmagick-6.2.6-win-im-6.2.9.zip
4:把q16目录下的jmagick.dll复制到D:\Tomcat5.0\bin下—:\tomcat是安装路径)
5:把jar_15目录下的jmagick.jar复制到%JAVA_HOME%\jre\lib\ext.
6:完毕,测试
?
PS:
web应用如果部署到tomcat下,那么最好在catalina.bat文件中改变如下设置
set JAVA_OPTS=%JAVA_OPTS% -Xms256M -Xmx768M -XX:MaxPermSize=128M -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -Djava.util.logging.config.file="${catalina.base}\conf\logging.properties"
避免heap溢出的问题,参数看你自己的机器而定。( -Xms256M -Xmx768M -XX:MaxPermSize=128M )
?
?
下面把jmagick-6.2.6-win-im-6.2.9目录下的说明文档附在这里,注意看他的Getting Started和Notes部分
This archive contains jmagick.dll 6.2.6 compiled against?
ImageMagick 6.2.9.
q8 contains jmagick.dll compiled against ImageMagick 6.2.9-Q8
http://www.imagemagick.org/download/binaries/ImageMagick-6.2.9-4-Q8-windows-dll.exe
q16 contains jmagick.dll compiled against ImageMagick 6.2.9-Q16
http://www.imagemagick.org/download/binaries/ImageMagick-6.2.9-4-Q16-windows-dll.exe
It was built with gcc mingw 3.4.2 on Windows 2000 and Sun JDK 1.5.0 release 5.
Getting Started:
1. Install ImageMagick
2. Copy the jmagick.dll corresponding with the Q8 or Q16 ImageMagick you installed to?
??? somewhere in your PATH. I would put it in the same directory as ImageMagick.
3. Put jmagick.jar in your java classpath. If you are using Tomcat, or other java
??? applications which have their own classloaders, move the jar up to a more global scope.
??? If you had placed the jar in WEB-INF/lib and reload the webapp, java will attempt to?
??? reload jmagick.dll twice, and it will fail. By moving the jar up, the library will only
??? be loaded once per jvm lifetime. I place mine in %JAVA_HOME%\jre\lib\ext.
Notes:
-------------------------------------------------------------
If you see exceptions such as UnsatisfiedLinkError, you did one of the above steps incorrectly
or you are not using the JVM/ImageMagick versions you think you are. Have your java code
print out the java.library.path -- System.getProperty("java.library.path"). Check to ensure
that jmagick.dll is in one of those directories.
-------------------------------------------------------------
If you run your java application as a service, any changes to the PATH environment variable will
not be visible to java until you reboot.
-------------------------------------------------------------
This is the first time I have built jmagick.dll using gcc/mingw. Let me know if you have any issues.
Mark Deneen
mdeneen at gmail dot com
?
---------------------------------------------------------
例子:
/**?
???? * 以正方形比例输出缩放图片
???? *?
???? * MaxBorderLen : 正方形边长
*/?
??? public void CoutImage4Square(String srcImage, String DestImage, int MaxBorderLen){
????
??? System.setProperty("jmagick.systemclassloader","no");
????
??? try{??
??? ?? ImageInfo info = new ImageInfo(srcImage);
??? ?? MagickImage image = new MagickImage(info);
??? ??
??? ?? //取长宽
??? ?? Dimension dim = image.getDimension();
??? ?? double wImage = dim.getWidth();
??? ?? double hImage = dim.getHeight();
??? ??
??? ?? Boolean bWBig = wImage > hImage? true:false ;
??? ??
??? ?? if (bWBig)
??? ?? {//长大过高
??? ??? hImage = MaxBorderLen * ( hImage / wImage);
??? ??? wImage = MaxBorderLen;
??? ?? }
??? ?? else
??? ?? {//反之
??? ??? wImage = MaxBorderLen * ( wImage / hImage);
??? ??? hImage = MaxBorderLen;
??? ?? }
??? ?? //输出
??? ?? MagickImage scaled = image.scaleImage((int)wImage, (int)hImage);
??? ?? scaled.setFileName(DestImage);???
??? ?? scaled.writeImage(info);??
??? ?? }catch(MagickApiException ex){
??? ?? }catch(MagickException ex){
??? }
??? }
?
?
-------------------------------------------------
JMagick是一个开源API,利用JNI(Java Native Interface)技术实现了对ImageMagickAPI的Java访问接口,因此也将比纯Java实现的图片操作函数在速度上要快。JMagick只实现了ImageMagicAPI的一部分功能,它的发行遵循LGPL协议。
ImageMagick请参考其官方网站或ImageMagick学习。
?
下载安装
安装要求:
- 如果通过CVS下载的源码,则需要GNU Autoconf
- GNU Make 3.77或更新版本(我用的是3.7.9).
- 一个ANSI C 编译器,建议用 GNU 或 EGCS 的编译器
- ImageMagick 5.5.6或更新版本
- Java2 JDK( JMagick是在 Sun JDK 1.4.1上开发,但运行好象不用那么高,我用的是1.3.1)
下载过程如下:
用CVS取源码:
?????? logger.error("MagickException: " + ex + ": " + ex.getReason() + ", " + ex.getDescription());
???? } catch(MagickException ex) {
?????? logger.error("MagickException: " + ex);
???? }
?? }
}
注意,需要将编译JMagick生成的lib/jmagick.jar包,复制到$TOMCATHOME/webapps/yourproject/WEB-INF/lib目录下。
******************************************************************************************************************************
---------------------------------------------------------
?
MagickImage大家可能都用过,它主要处理一些图片,它可以处理90多种的图片类型.它的功能非常强大,而我们在实际的应用中,主要用到它的缩放,截取,复制功能。其他的一些如写入文字,加背景色,旋转。。。用的少。
??? 第一个常用的功能缩放(scaleImage)。
??? 首先初始化一个ImageInfo对象,就是加载要处理的图片路径.
??? ImageInfo info= new ImageInfo(“F:\\images\\1.jpg”);?
??? 然后再把图片信息ImageInfo作为构造MagickImage的参数传入。 MagickImage 是处理图片的主要类。????????????????????????????????????????????????????????????????????????????????????????????????????
??? MagickImage image= new MagickImage(info);
??? 再对MagickImage的对象选取方法。进行缩放。scaleImage(w, h),第一个参数指按比例缩放后的宽度,第二个就是高度了。
??? MagickImage cropped= image .scaleImage(40, 80);
??? 最后把处理完的图片命名(1_scale.jpg)存放到指定的目录下(F:/images)。?
??? cropped.setFileName("F:\\images\\1_scale.jpg");
??? writeImage指定源图片的ImageInfo 对象。
??? cropped.writeImage(info);
????
??? 这样就简单的把原来的图片缩放成40X80的1_scale.jpg新图片了。
??? 第二个常用的功能截取(cropImage)。
??? 首先初始化一个ImageInfo对象,就是加载要处理的图片路径.
??? ImageInfo info= new ImageInfo(“F:\\images\\1.jpg”);?
??? 再初始化一个合适的宽度和高度,以及起始坐标。就是要处理后图片的大小形状(矩形)。
??? Rectangle rect = new Rectangle(0, 0, 40, 80);
??? x,y就是起始点的坐标,一般从图片的左上角开始,默认为0.w,h就是实际的宽度和高度了,不是按比例截取后的宽度和高度。
??? 这一点与上面的不同。
??? 然后再把图片信息ImageInfo作为构造MagickImage的参数传入。 MagickImage 是处理图片的主要类。????????????????????????????????????????????????????????????????????????????????????????????????????
??? MagickImage image= new MagickImage(info);
??? 再对MagickImage的对象选取方法。进行实际大小的截取。cropImage(rect),参数指图片的范围。
??? MagickImage cropped = image.cropImage(rect);
??? 最后把处理完的图片命名(1_crop.jpg)存放到指定的目录下(F:/images)。?
??? cropped.setFileName("F:\\images\\1_crop.jpg");
??? writeImage指定源图片的ImageInfo 对象。
??? cropped.writeImage(info);
????
??? 这样就简单的把原来的图片截取成40X80的1_crop.jpg新图片了。原图片的规格一定大于40X80,要不然截取的有空白了。自己试试就知道了。
????
???
??? 最后一个常用的功能复制(copy),这个最简单了。
??? 首先初始化一个ImageInfo对象,就是加载要处理的图片路径.
??? ImageInfo info= new ImageInfo(“F:\\images\\1.jpg”);?
???
??? 然后再把图片信息ImageInfo作为构造MagickImage的参数传入。 MagickImage 是处理图片的主要类。????????????????????????????????????????????????????????????????????????????????????????????????????
??? MagickImage image= new MagickImage(info);
??? 最后把处理完的图片命名(1_copy.jpg)存放到指定的目录下(F:/images)。?
??? image.setFileName("F:\\images\\1_copy.jpg");
??? writeImage指定源图片的ImageInfo 对象。
??? image.writeImage(info);
??? 这个没有用到(cloneImage)方法,简单的理解为改变图片的存放路径就可以了,这样就很轻松的实现了copy了,比它自带的cloneImage简单多了。
******************************************************************************************************************************
?
你好,我最近也在看基于JAVA的图像处理:
你看看这个如何:ImageJ
http://www.infomall.cn/cgi-bin/mallgate/20040514/http://rsb.info.nih.gov/ij/
我想利用这个包将图片动态生成各种幅面的缩略图(包含站点水印)。然后图片可以通过PATH_INFO解析参数,比如生成一个200*150的水印:
http://www.infomall.cn/cgi-bin/mallgate/20040514/http://www.chedong.com/thumb/200/150/orig.jpg