由于项目需要处理图片的质量,在将图片上传到网站或从网站下载图片的时候需要处理图片的大小水印等,经过网上查找和朋友的推荐使用Jmagick来处理会效果会比较好,下面就记录使用Jmagick过程当中遇到的问题。
首先我从官网http://downloads.jmagick.org/下载了最新版本的jmagick,我在window下使用的是jmagick-win-6.3.9-Q8.zip和ImageMagick-6.3.9-0-Q8-windows-dll.exe,首先安装ImageMagick-6.3.9-0-Q8-windows-dll.exe这个文件,默认是安装在C:\Program Files\ImageMagick-6.3.9-Q8这个目录中,然后将此目录当中的所有dll文件(有可能msvcp71.dll和msvcr71.dll这两个文件拷贝的时候会提示正在使用中,我们可以不用拷这两个文件,我试了是可以的)拷贝到WINDOWS\system32文件夹下。并将jmagick-win-6.3.9-Q8.zip这个压缩包中的jmagick.dll文件拷贝到C:\Program Files\ImageMagick-6.3.9-Q8和jdk的bin这两个目录中,并将jmagick.jar拷贝到项目当中。最后还需要将C:\Program Files\ImageMagick-6.3.9-Q8添加到PATH环境变量当中。这时基本的配置工作已经完成,下面就是使用jmagick.jar这个包中的一些API了,主要是对ImageInfo,MagickImage和Dimension这三个类的使用。
看了ImageInfo的代码,它继承了Magick这个类,Magick这个类中只有两个native方法和一个static代码块,native方法这里就不解释了,我想是用来初始化处理图片的一些基本功能,主要看下static代码块:
static { String s = System.getProperty("jmagick.systemclassloader"); if(s == null || s.equalsIgnoreCase("yes")) try { ClassLoader.getSystemClassLoader().loadClass("magick.MagickLoader").newInstance(); } catch(ClassNotFoundException classnotfoundexception) { throw new RuntimeException("Can't load MagickLoader (class not found)"); } catch(IllegalAccessException illegalaccessexception) { throw new RuntimeException("Access to SystemClassLoader denied (IllegalAccessException)"); } catch(InstantiationException instantiationexception) { throw new RuntimeException("Can't instantiate MagicLoader (InstantiationException)"); } else System.loadLibrary("JMagick"); init(); }首先是使用System类得到 jmagick.systemclassloader的值,这个值我们是需要在自己的代码当中显式指定的,基本上我们都指定为no,这样System就会去加载刚刚我们放进去的jmagick.dll这个类库。
ImageInfo类中除了两个构造函数外其他的都是native方法,native方法也是一些获得图片的一些基本信息,比如大小,文件名,字体等等信息,主要是一个带参的构造方法,用来设置图片的文件名为那个方法的参数。
MagickImage类也是继承了Magick这个类,这个类的主要功能是读写图片的信息,是真正来处理图片的类,这个类有五个构造方法,我们经常会使用的我觉得是
public MagickImage(ImageInfo imageinfo) throws MagickException { magickImageHandle = 0L; readImage(imageinfo); }这个构造方法,此构造方法接收一个ImageInfo类作为参数,然后读取此图片的信息。
然后就是Dimension这个类,此类继承了Dimension2D这个抽象类,Dimension2D这个类很简单:
protected Dimension2D() { } public abstract double getWidth(); public abstract double getHeight(); public abstract void setSize(double d, double d1); public void setSize(Dimension2D dimension2d) { setSize(dimension2d.getWidth(), dimension2d.getHeight()); } public Object clone() { try { return super.clone(); } catch(CloneNotSupportedException clonenotsupportedexception) { throw new InternalError(); } }下面来看一下awt包中的Dimension这个类,就是对图片的宽高进行获取和设置:
private static native void initIDs(); public Dimension() { this(0, 0); } public Dimension(Dimension dimension) { this(dimension.width, dimension.height); } public Dimension(int i, int j) { width = i; height = j; } public double getWidth() { return (double)width; } public double getHeight() { return (double)height; } public void setSize(double d, double d1) { width = (int)Math.ceil(d); height = (int)Math.ceil(d1); } public Dimension getSize() { return new Dimension(width, height); } public void setSize(Dimension dimension) { setSize(dimension.width, dimension.height); } public void setSize(int i, int j) { width = i; height = j; } public boolean equals(Object obj) { if(obj instanceof Dimension) { Dimension dimension = (Dimension)obj; return width == dimension.width && height == dimension.height; } else { return false; } } public int hashCode() { int i = width + height; return (i * (i + 1)) / 2 + width; } public String toString() { return (new StringBuilder()).append(getClass().getName()).append("[width=").append(width).append(",height=").append(height).append("]").toString(); } public int width; public int height; private static final long serialVersionUID = 4723952579491349524L; static { Toolkit.loadLibraries(); if(!GraphicsEnvironment.isHeadless()) initIDs(); }注意最后的静态代码块,初始化这个类时会执行这里面的代码, Toolkit.loadLibraries()这个方法主要是去加载awt的相关类,所以我觉得到最后还是需要用到java的awt包中的类来进行图片的处理。
这篇文章主要是对Jmagick包中的几个常用类进行了简单分析,下一篇会有一个实际的处理图片的应用。