JMagic 操作 ImageMagick 处理图片

项目描述

imagemagick是功能强大的图片处理库,以稳定及高效率著称,众多语言对该库进行封装处理。比如php、java。由于我们是java项目,直接使用java通过JNI技术调用ImageMagick是不行的。因为ImageMagick开发时没有使用java JNI生成的头文件。可以使用JMagick解决,JMagick是由c语言开发的,开发时使用了java JNI生成的头文件,所以java可以通过JNI技术调用JMagick。JMagick再调用ImageMagick。这里我们处理图片使用的是JMagick暴露的java接口。

下载和安装

Windows安装使用Jmagick及imagemagick步骤如下:

1、访问jmagick网站下载: http://downloads.jmagick.org

2、目前JMagick只有32位的,所以只能选择32位的ImageMagick,并且版本支持很低,目前只到ImageMagick-6.3.9-0,只能使用32位的JDK,64位进程不能够调用32位的dll,想在64位的系统上用jmagick不仅要将jdk换成32位,而且jmagick.dll也得放到SysWOW64下面,不能放到System32中。

3、下载两个文件:红框的两个或者绿框的两个。

关于Q8,Q16,Q32的说明:(建议使用8,现在数码相机照的相片,每一种颜色就是8位深,3种颜色就是24位,所以选8) 
支持的参数有3种,分别是 8,16,32。默认值是16。 
Q8表示: 8-bits per pixel quantum 
Q16表示:16-bits per pixel quantum 
Q32表示:32-bits per pixel quantum 

使用16-bit per pixel quantums在处理图片时比8-bit慢15%至50%,并须要更多的内存。 
处理一张1024x768像素的图片8-bit要使用3.6M内存,16-bit要使用7.2M内存。计算方法是: (5 * Quantum Depth * Rows * Columns) / 8 

大多数电脑显示使用8-bit per pixel quantums。使用16-bit per pixel quantums在处理图片时比8-bit慢15%至50%,并须要更多的内存。比如处理一张1024x768像素的图片8-bit要使用3M内存,16-bit要使用8M内存。8-bit可表示0-255种值,16-bit可表示0-65535种值。默认值是8-bit。
另外Windows下有动态版(dll),有静态版(static),这里使用了动态版。

4、下载时注意版本问题。不要到imagemagick官方网站下载imagemagick,这样会导致下载的imagemagick版本和jmagick版本不对应,导致调用出现异常。比如出现memor allocate not enough 的异常。

这是我下载出来的文件(我公司电脑系统是WIN7-32位,安装的也是32位的JDK):

5、双击下载的ImageMagick-6.3.9-0-Q8-windows-dll.exe文件安装即可,一直点击下一步就可以。这里如果勾选了红框标注的选项,环境变量会自动配好的。

在命令行使用

到这里就可以在DOS命令窗口中使用了,具体使用命令可以参考这篇博客:http://www.charry.org/docs/linux/ImageMagick/ImageMagick.html,下面截图演示对桌面图片的处理:

在Java中使用

1、将ImageMagick安装目录下的所有的.dll文件复制到  C:/ windows/System32的目录下(这一步有可能省略,等待验证)

2、解压jmagick-win-6.3.9-Q8.zip , 将jmagick.dll放到 C:/windows/System32 目录下。这里是为了能在Java中使用jmagick的类进行操作ImageMagick,如果不复制的话,会报UnsatisfiedLinkError: no JMagick in java.library.path.异常。

3、将jmagick.jar加入到eclipse下相关项目的build path中的libraries  中即完成了相应的安装。接下来就可以在java项目中使用了。

4、Java中通过jmagick操作ImageMagick,示例代码:

  1 package com.demo.test;   
  2  
  3 import java.awt.Dimension;
  4 import java.awt.Rectangle;
  5 import java.text.SimpleDateFormat;
  6 import java.util.Date;   
  7  
  8 
  9 import magick.CompositeOperator;
 10 import magick.CompressionType;
 11 import magick.DrawInfo;
 12 import magick.ImageInfo;
 13 import magick.MagickException;
 14 import magick.MagickImage;
 15 import magick.PixelPacket;
 16 import magick.PreviewType;   
 17  
 18 public class ImageTools {   
 19  
 20     static{
 21         //不能漏掉这个,不然jmagick.jar的路径找不到
 22         //System.setProperty("jmagick.systemclassloader","no");
 23     }   
 24  
 25     /**
 26      * 压缩图片
 27      * @param filePath 源文件路径
 28      * @param toPath   缩略图路径
 29      */
 30     public static void createThumbnail(String filePath, String toPath) throws MagickException{
 31         ImageInfo info = null;
 32         MagickImage image = null;
 33         Dimension imageDim = null;
 34         MagickImage scaled = null;
 35         try{
 36             info = new ImageInfo(filePath);
 37             image = new MagickImage(info);
 38             imageDim = image.getDimension();
 39             int wideth = imageDim.width;
 40             int height = imageDim.height;
 41             if (wideth > height) {
 42                 height = 660 * height / wideth;
 43                 wideth = 660;
 44             }
 45             scaled = image.scaleImage(wideth, height);//小图片文件的大小.
 46             scaled.setFileName(toPath);
 47             scaled.writeImage(info);
 48         }finally{
 49             if(scaled != null){
 50                 scaled.destroyImages();
 51             }
 52         }
 53     }   
 54  
 55     /**
 56      * 水印(图片logo)
 57      * @param filePath  源文件路径
 58      * @param toImg     修改图路径
 59      * @param logoPath  logo图路径
 60      * @throws MagickException
 61      */
 62     public static void initLogoImg(String filePath, String toImg, String logoPath) throws MagickException {
 63         ImageInfo info = new ImageInfo();
 64         MagickImage fImage = null;
 65         MagickImage sImage = null;
 66         MagickImage fLogo = null;
 67         MagickImage sLogo = null;
 68         Dimension imageDim = null;
 69         Dimension logoDim = null;
 70         try {
 71             fImage = new MagickImage(new ImageInfo(filePath));
 72             imageDim = fImage.getDimension();
 73             int width = imageDim.width;
 74             int height = imageDim.height;
 75             if (width > 660) {
 76                 height = 660 * height / width;
 77                 width = 660;
 78             }
 79             sImage = fImage.scaleImage(width, height);   
 80  
 81             fLogo = new MagickImage(new ImageInfo(logoPath));
 82             logoDim = fLogo.getDimension();
 83             int lw = width / 8;
 84             int lh = logoDim.height * lw / logoDim.width;
 85             sLogo = fLogo.scaleImage(lw, lh);   
 86  
 87             sImage.compositeImage(CompositeOperator.AtopCompositeOp, sLogo,  width-(lw + lh/10), height-(lh + lh/10));
 88             sImage.setFileName(toImg);
 89             sImage.writeImage(info);
 90         } finally {
 91             if(sImage != null){
 92                 sImage.destroyImages();
 93             }
 94         }
 95     }   
 96  
 97     /**
 98      * 水印(文字)
 99      * @param filePath 源文件路径
100      * @param toImg    修改图路径
101      * @param text     名字(文字内容自己随意)
102      * @throws MagickException
103      */
104     public static void initTextToImg(String filePath, String toImg,  String text) throws MagickException{
105             ImageInfo info = new ImageInfo(filePath);
106             if (filePath.toUpperCase().endsWith("JPG") || filePath.toUpperCase().endsWith("JPEG")) {
107                 info.setCompression(CompressionType.JPEGCompression); //压缩类别为JPEG格式
108                 info.setPreviewType(PreviewType.JPEGPreview); //预览格式为JPEG格式
109                 info.setQuality(95);
110             }
111             MagickImage aImage = new MagickImage(info);
112             Dimension imageDim = aImage.getDimension();
113             int wideth = imageDim.width;
114             int height = imageDim.height;
115             if (wideth > 660) {
116                 height = 660 * height / wideth;
117                 wideth = 660;
118             }
119             int a = 0;
120             int b = 0;
121             String[] as = text.split("");
122             for (String string : as) {
123                 if(string.matches("[\u4E00-\u9FA5]")){
124                     a++;
125                 }
126                 if(string.matches("[a-zA-Z0-9]")){
127                     b++;
128                 }
129             }
130             int tl = a*12 + b*6 + 300;
131             MagickImage scaled = aImage.scaleImage(wideth, height);
132             if(wideth > tl && height > 5){
133                 DrawInfo aInfo = new DrawInfo(info);
134                 aInfo.setFill(PixelPacket.queryColorDatabase("white"));
135                 aInfo.setUnderColor(new PixelPacket(0,0,0,100));
136                 aInfo.setPointsize(12);
137                 //解决中文乱码问题,自己可以去随意定义个自己喜欢字体,我在这用的微软雅黑
138                 String fontPath = "C:/WINDOWS/Fonts/MSYH.TTF";
139                 //String fontPath = "/usr/maindata/MSYH.TTF";
140                 aInfo.setFont(fontPath);
141                 aInfo.setTextAntialias(true);
142                 aInfo.setOpacity(0);
143                 aInfo.setText(" " + text + "于 " + new SimpleDateFormat("yyyy-MM-dd").format(new Date()) + " 上传于我的相册网,版权归作者所有!");
144                 aInfo.setGeometry("+" + (wideth-tl) + "+" + (height-5));
145                 scaled.annotateImage(aInfo);
146             }
147             scaled.setFileName(toImg);
148             scaled.writeImage(info);
149             scaled.destroyImages();
150     }   
151  
152     /**
153      * 切图
154      * @param imgPath 源图路径
155      * @param toPath  修改图路径
156      * @param w
157      * @param h
158      * @param x
159      * @param y
160      * @throws MagickException
161      */
162     public static void cutImg(String imgPath, String toPath, int w, int h, int x, int y) throws MagickException {
163         ImageInfo infoS = null;
164         MagickImage image = null;
165         MagickImage cropped = null;
166         Rectangle rect = null;
167         try {
168             infoS = new ImageInfo(imgPath);
169             image = new MagickImage(infoS);
170             rect = new Rectangle(x, y, w, h);
171             cropped = image.cropImage(rect);
172             cropped.setFileName(toPath);
173             cropped.writeImage(infoS);   
174  
175         } finally {
176             if (cropped != null) {
177                 cropped.destroyImages();
178             }
179         }
180     }
181     
182     /**
183      * 测试
184      * @param args
185      */
186     public static void main(String[] args) {
187         try {
188              cutImg("C:\\Users\\Administrator\\Desktop\\test\\new3.jpg", "C:\\Users\\Administrator\\Desktop\\test\\new5.jpg", 100, 100, 300, 150);
189         } catch (MagickException e) {
190             e.printStackTrace();
191         }
192     }
193 }

 

posted @ 2017-07-03 15:55  一线大码  Views(2265)  Comments(0Edit  收藏  举报