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

jopen 10年前

做网站往往需要处理各种各样的图片,对于jdk自带的一套图片处理库,他的特点是稳定简单,但是对图片处理来说,性能确实很不咋的!
        于是我转向了以C++处理为核心的java处理包—— JMagick+ ImageMagick 。jmagick是一个开源的API,利用JNI(Java Native Interface)技术实现了对ImageMagickAPI 的Java访问接口,因此也将比纯Java实现的图片操作函数在速度上要快。实地测试后发现,速度果然提高了不少,但是质量却大大下降了,在大量测试数据下,每生成100张图片约会有5张图片生成出现错误,还会出现down机的情况。对于一个商业应用来说,这个是绝对不可以接受的,于是对jmagick的研究暂放一段时间。
        经过韩boss指导,我转向了 GraphicsMagick+im4java 的研究,输入关键词google一下,很容易就可以找到http://javantsky.iteye.com/blog/747807 ,这篇博客,文章介绍GraphicsMagick+im4java 性能高,运行稳定!

注意事项:如果是在windows下运行,则需要配置ImageMagick的安装路径: 
我是配置在config.properties文件里了,比如内容如下所示: 
imageMagickPath=C://Program Files//GraphicsMagick-1.3.14-Q16
如果是在linux平台下,则不需要配置。

package imageUtils;    import java.io.IOException;  import java.util.ArrayList;    import org.im4java.core.ConvertCmd;  import org.im4java.core.IMOperation;    /**   * @author hegh E-mail: heguanhua@tjhq.com   * @version 创建时间:Mar 13, 2012 10:43:12 AM 类说明   */  public class ImageMagick {     /** * ImageMagick的路径 */    public static String imageMagickPath = null;     static{ /**获取ImageMagick的路径 */      //Properties prop = new PropertiesFile().getPropertiesFile();      //linux下不要设置此值,不然会报错     //imageMagickPath = prop.getProperty("imageMagickPath");     }         /** * 根据坐标裁剪图片    * @param srcPath 要裁剪图片的路径     * @param newPath 裁剪图片后的路径     * @param x 起始横坐标     * @param y 起始挫坐标     * @param x1 结束横坐标     * @param y1 结束挫坐标     */     public static void cutImage(String srcPath, String newPath, int x, int y, int x1, int y1)     throws Exception {      int width = x1 - x; int height = y1 - y;      IMOperation op = new IMOperation();      op.addImage(srcPath);      /**      * width:裁剪的宽度       * height:裁剪的高度       * x:裁剪的横坐标       * y:裁剪的挫坐标       */      op.crop(width, height, x, y);     op.addImage(newPath);      ConvertCmd convert = new ConvertCmd();     //linux下不要设置此值,不然会报错      //convert.setSearchPath(imageMagickPath);     convert.run(op);    }         /**      * 根据尺寸缩放图片      * @param width 缩放后的图片宽度      * @param height 缩放后的图片高度      * @param srcPath 源图片路径      * @param newPath 缩放后图片的路径      * @param type 1为比例处理,2为大小处理,如(比例:1024x1024,大小:50%x50%)     */     public static String cutImage(int width, int height, String srcPath, String newPath,int type,String quality) throws Exception {      IMOperation op = new IMOperation();            ConvertCmd cmd = new ConvertCmd(true);      op.addImage();      String raw = "";     if(type == 1){      //按像素      raw = width+"x"+height+"^";     }else{      //按像素百分比      raw = width+"%x"+height+"%";     }       op.addRawArgs("-sample" ,  raw );        if((quality !=null && quality.equals(""))){      op.addRawArgs("-quality" ,  quality );      }     op.addImage();             String osName = System.getProperty("os.name").toLowerCase();     if(osName.indexOf("win") != -1) {      //linux下不要设置此值,不然会报错      cmd.setSearchPath("C://Program Files//GraphicsMagick-1.3.14-Q16");      }       try{      cmd.run(op, srcPath, newPath);             }catch(Exception e){      e.printStackTrace();     }     return newPath;   }           /**     * 给图片加水印    * @param srcPath 源图片路径     */     public static void addImgText(String srcPath) throws Exception {      IMOperation op = new IMOperation();        op.font("宋体").gravity("southeast").pointsize(18).fill("#BCBFC8").draw("text 100,100 co188.com");       op.addImage();      op.addImage();              String osName = System.getProperty("os.name").toLowerCase();         ConvertCmd cmd = new ConvertCmd(true);      if(osName.indexOf("win") != -1) {      //linux下不要设置此值,不然会报错      cmd.setSearchPath("C://Program Files//GraphicsMagick-1.3.14-Q16");      }       try{      cmd.run(op, srcPath, srcPath);             }catch(Exception e){      e.printStackTrace();     }    }         public static void main(String[] args) throws Exception{      //cutImage("D:\\apple870.jpg", "D:\\apple870eee.jpg",98, 48, 370, 320);      Long start = System.currentTimeMillis();     //cutImage(100,100, "e:\\37AF7D10F2D8448A9A5.jpg","e:\\37AF7D10F2D8448A9A5_bak2.jpg",2,"100");      addImgText("e:\\37AF7D10F2D8448A9A5_bak2.jpg");      Long end = System.currentTimeMillis();     System.out.println("time:"+(end-start)/3600);    }  }  通过GraphicsMagick+im4java实现高质量大图的处理,解决了100M以上,以及图片像素10000以上处理是出现内存溢出的问