• 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 }
  • 相关阅读:
    Bootstrap中的Dropdown悬停触发
    git常用命令整理
    ThinkPHP-项目模块分组后自定义类库文件放去哪?
    项目开发中常用的PHP实用代码算法
    1049. Counting Ones (30)
    1059. Prime Factors (25)
    1050. String Subtraction (20)
    观察者模式
    策略模式
    JVM剖析
  • 原文地址:https://www.cnblogs.com/wbxk/p/7111531.html
Copyright © 2020-2023  润新知