im4java + imagemagic 搭建一個圖片處理服務

imagemagic + im4java 進行圖片處理

利用 imagemagic 對圖片進行處理,java工程中,使用im4java來操做imagemagic的apiphp

1、環境

how to install ?java

linux 系統,安裝以前,須要先安裝 libjpeg libpng包,不然無法處理jpg和png圖片linux

1. 下載依賴包

  • 安裝jpeg 包 wget ftp://223.202.54.10/pub/web/php/libjpeg-6b.tar.gz
  • 安裝webp 包 wget http://www.imagemagick.org/download/delegates/libwebp-0.5.1.tar.gz
  • 安裝png 包 wget http://www.imagemagick.org/download/delegates/libpng-1.6.24.tar.gz
  • 安裝 graphicsmagick wget http://nchc.dl.sourceforge.net/project/graphicsmagick/graphicsmagick/1.3.22/GraphicsMagick-1.3.22.tar.gz
  • 安裝imagemagick wget http://www.imagemagick.org/download/ImageMagick.tar.gz

2. 安裝

首先安裝lib包,而後在安裝 graphicmagick or imagemagickweb

安裝方式:api

sudo ./configure
sudo make
sudo make install

3. 測試

gm 裁圖 gm convert -crop 640x960+0+0 test.jpg output.jpgtomcat

im 裁圖 convert test.jpg -crop 640x960+0+0 output.jpgapp

4. 安裝問題

linux 安裝以後,可能有兩個問題ide

  • imagemagick 依然沒法讀取png圖片函數

    png包安裝完成後,將路徑添加到環境變量測試

    export CPPFLAGS='-I/usr/local/include'
    export LDFLAGS="-L/usr/local/lib"
  • 執行 convert 提示linux shared libraries 不包含某個庫

    臨時解決方案: export LD_LIBRARY_PATH=/usr/local/lib:$LD_LIBRARY_PATH

    一勞永逸的方案:https://my.oschina.net/guanyue/blog/220264

    vi /etc/ld.so.conf
       在這個文件里加入:/usr/local/lib 來指明共享庫的搜索位置
       而後再執行/sbin/ldconf

2、 ImageMagic經常使用命令

  1. 裁圖的命令

    convert test.jpg -crop 360x720+0+0 out.jpg

    -gravity即指定座標原點,有northwest:左上角,north:上邊中間,northeast:右上角,east:右邊中間

    convert image.png -gravity northeast -crop 100x100+0+0 crop.png

  2. 旋轉圖片的命令

    convert test.jpg -rotate 90 out.jpg

    默認的背景爲白色,咱們能夠指定背景色:

    convert image.png -backround black -rotate 45 rotate.png convert image.png -background #000000 -rotate 45 rotate.png

  3. 圖片放大縮小的命令

    • resize: 拉伸收縮
    • sample: 與resize的區別在於-sample只進行了採樣,沒有進行插值,因此用來生成縮略圖最合適

    convert test.jpg -resize 512x512 out.jpg convert image.png -sample 50% sample.png

    如馬賽克效果:

    convert image.png -sample 10% -sample 1000% sample.png

  4. 旋轉並裁圖

    convert test.jpg -rotate 90 -crop 360x720+0+0 out.jpg

  5. 添加文字

    convert image.png -draw "text 0,20 'some text'" newimage.png

    convert source.jpg -font xxx.ttf -fill red -pointsize 48 -annotate +50+50 @text.txt result.jpg

  6. 格式轉換

    convert image.png -define png:format=png32 newimage.png convert image.png image.jpg

  7. 拼接

    橫向拼接(+append),下對齊(-gravity south): convert image1.png image2.png image3.png -gravity south +append result.png

    縱向拼接(-append),右對齊(-gravity east): convert image1.png image2.png image3.png -gravity east -append result.png

  8. 圖片信息

    identify test.png

    獲取寬高 identify -format "%wx%h" image.png

3、編碼實測

使用im4javaimagemagic進行調用, im4java 其實最終是生成cmd命令,系統調用實現,jmagic是一個使用jni的方式進行調用的開源包,根據網上說法是,放在tomcat,過一段時間會crash,這裏沒有進行實測,直接選取了 im4java

package com.hust.hui.wolf.base.util.img;

import org.im4java.core.CompositeCmd;
import org.im4java.core.ConvertCmd;
import org.im4java.core.IM4JavaException;
import org.im4java.core.IMOperation;

import java.io.IOException;

/**
 * 圖片裁剪\旋轉\拉伸\加水印
 * Created by yihui on 16/10/31.
 */
public class ImgOperateUtil {

    /**
     * 裁剪圖片
     *
     * @param imagePath 源圖片路徑
     * @param outPath   處理後圖片路徑
     * @param x         起始X座標
     * @param y         起始Y座標
     * @param width     裁剪寬度
     * @param height    裁剪高度
     * @return 返回true說明裁剪成功, 不然失敗
     */
    public static boolean cut(String imagePath, String outPath, int x, int y,
                              int width, int height) {
        boolean flag;
        try {
            IMOperation op = new IMOperation();
            op.addImage(imagePath);
            /** width:裁剪的寬度 * height:裁剪的高度 * x:裁剪的橫座標 * y:裁剪縱座標 */
            op.crop(width, height, x, y);
            op.addImage(outPath);
            // 傳true到構造函數中,則表示使用GraphicMagic, 裁圖時,圖片大小會變
            ConvertCmd convert = new ConvertCmd();
            convert.run(op);
            flag = true;
        } catch (IOException e) {
            flag = false;
        } catch (InterruptedException e) {
            flag = false;
        } catch (IM4JavaException e) {
            flag = false;
        }
        return flag;
    }

    /**
     * 圖片旋轉
     *
     * @param imagePath 源圖片路徑
     * @param outPath   處理後圖片路徑
     * @param degree    旋轉角度
     */
    public static boolean rotate(String imagePath, String outPath, double degree) {
        try {
            // 1.將角度轉換到0-360度之間
            degree = degree % 360;
            if (degree <= 0) {
                degree = 360 + degree;
            }
            IMOperation op = new IMOperation();
            op.addImage(imagePath);
            op.rotate(degree);
            op.addImage(outPath);
            ConvertCmd cmd = new ConvertCmd();
            cmd.run(op);
            return true;
        } catch (IOException e) {
            return false;
        } catch (InterruptedException e) {
            return false;
        } catch (IM4JavaException e) {
            return false;
        }
    }


    /**
     * 旋轉並裁圖
     *
     * @param imgPath 原始圖片
     * @param outPath 輸出圖片
     * @param degree  旋轉角度
     * @param x       起始值 x座標
     * @param y       起始Y座標
     * @param width   裁圖寬
     * @param height  裁圖高
     * @return
     */
    public static boolean rotateAndCut(String imgPath, String outPath, double degree,
                                       int x, int y, int width, int height) {
        try {
            // 1.將角度轉換到0-360度之間
            degree = degree % 360;
            if (degree <= 0) {
                degree = 360 + degree;
            }
            IMOperation op = new IMOperation();
            op.addImage(imgPath);
            op.rotate(degree);
            op.crop(width, height, x, y);
            op.addImage(outPath);
            ConvertCmd cmd = new ConvertCmd();
            cmd.run(op);
            return true;
        } catch (IOException e) {
            return false;
        } catch (InterruptedException e) {
            return false;
        } catch (IM4JavaException e) {
            return false;
        }
    }


    /**
     * 根據尺寸縮放圖片[等比例縮放:參數height爲null,按寬度縮放比例縮放;參數width爲null,按高度縮放比例縮放]
     *
     * @param imagePath 源圖片路徑
     * @param newPath   處理後圖片路徑
     * @param width     縮放後的圖片寬度
     * @param height    縮放後的圖片高度
     * @return 返回true說明縮放成功, 不然失敗
     */
    public static boolean zoom(String imagePath, String newPath, Integer width,
                               Integer height) {

        boolean flag = false;
        try {
            IMOperation op = new IMOperation();
            op.addImage(imagePath);
            if (width == null) {// 根據高度縮放圖片
                op.resize(null, height);
            } else if (height == null) {// 根據寬度縮放圖片
                op.resize(width);
            } else {
                op.resize(width, height);
            }
            op.addImage(newPath);
            ConvertCmd convert = new ConvertCmd();
            convert.run(op);
            flag = true;
        } catch (IOException e) {
            System.out.println("文件讀取錯誤!");
            flag = false;
        } catch (InterruptedException e) {
            flag = false;
        } catch (IM4JavaException e) {
            flag = false;
        } finally {

        }
        return flag;
    }

    /**
     * 添加文字水印
     *
     * @param srcPath   原始圖片
     * @param destPath  目標圖片
     * @param text      文字   "text 5,5 'hello world'", 其中 hello world 爲要繪製的內容
     * @param fontType  文字字體  "宋體"
     * @param fontSize  字體大小  18
     * @param gravity   文字位置  "southeast"
     * @param fontColor 文字顏色 "#BCBFC8"
     * @throws Exception
     */
    public static boolean waterMark(String srcPath,
                                    String destPath,
                                    String text,
                                    String fontType,
                                    int fontSize,
                                    String gravity,
                                    String fontColor) {
        IMOperation op = new IMOperation();
        op.font(fontType).gravity(gravity).pointsize(fontSize).fill(fontColor)
                .draw(text);
        op.addImage();
        op.addImage();
        ConvertCmd convert = new ConvertCmd();
        try {
            convert.run(op, srcPath, destPath);
            return true;
        } catch (IOException e) {
            e.printStackTrace();
            return false;
        } catch (InterruptedException e) {
            e.printStackTrace();
            return false;
        } catch (IM4JavaException e) {
            e.printStackTrace();
            return false;
        }
    }


    /**
     * 圖片水印
     *
     * @param srcImagePath   源圖片
     * @param waterImagePath 水印
     * @param destImagePath  生成圖片
     * @param gravity        圖片位置
     * @param dissolve       水印透明度
     */
    public static boolean waterMark(String waterImagePath,
                                    String srcImagePath,
                                    String destImagePath,
                                    String gravity,
                                    int dissolve) {
        IMOperation op = new IMOperation();
        op.gravity(gravity);
        op.dissolve(dissolve);
        op.addImage(waterImagePath);
        op.addImage(srcImagePath);
        op.addImage(destImagePath);
        CompositeCmd cmd = new CompositeCmd();
        try {
            cmd.run(op);
            return true;
        } catch (IOException e) {
            e.printStackTrace();
            return false;
        } catch (InterruptedException e) {
            e.printStackTrace();
            return false;
        } catch (IM4JavaException e) {
            e.printStackTrace();
            return false;
        }
    }
}

單測能夠參考 com.hust.hui.wolf.base.tool.ImageUtilTest

相關文章
相關標籤/搜索