使用 Grapicmagick 和 Im4java 處理圖片
ImageMagick是個圖片處理工具可以安裝在絕大多數的平臺上使用,Linux、Mac、Windows都沒有問題。GraphicsMagick是在ImageMagick基礎上的另一個專案,大大提高了圖片處理的效能,在linux平臺上,可以使用命令列的形式處理圖片。Im4java 和Jmagick 都是開源社群為上面兩個工具開發的 Java API,效能和方便度上im4java是更好的選擇。
JMagick vs Im4Java
JMagick是一個開源API,利用JNI(Java Native Interface)技術實現了對ImageMagick API的Java訪問介面,因此也將比純Java實現的圖片操作函式在速度上要快。JMagick只實現了ImageMagicAPI的一部分功能,它的發行遵循LGPL協議。
im4java是ImageMagick的另一個Java開源介面。與JMagick不同之處在於im4java只是生成與ImageMagick相對應的命令列,然後將生成的命令列傳至選中的ImageCommand(使用java.lang.ProcessBuilder.start()實現)來執行相應的操作。它支援大部分ImageMagick命令,可以針對不同組的圖片多次複用同一個命令列。
im4java只是封裝ImageMagick的命令。所以不需要依賴dll,也不存在64位系統呼叫32位dll的問題.而且im4java支援GraphicsMagick,GraphicsMagick是ImageMagick的分支。相對ImageMagick ,GraphicsMagick更穩定,消耗資源更少。最重要的是不依賴dll環境
所以使用 im4java 是更好的選擇。
Im4java處理圖片示例
這篇文章主要是 im4java 的使用,而 im4java 又是對 GraphicsMagick 命令的封裝,GraphicsMagick 命令的使用可以看另一篇文章 GraphicsMagick 1.3.23 常用命令
先寫個包含獲取圖片資訊的簡單工具類,如下。
public class Im4JavaUtils {
private static Logger logger = LoggerFactory.getLogger(Im4JavaUtils.class);
// 圖片質量
public static final String IMAGE_QUALITY = "quality";
// 圖片高度
public static final String IMAGE_HEIGHT = "height";
// 圖片寬度
public static final String IMAGE_WIDTH = "width";
// 圖片格式
public static final String IMAGE_SUFFIX = "suffix";
// 圖片大小
public static final String IMAGE_SIZE = "size";
// 圖片路徑
public static final String IMAGE_PATH = "path";
/**
* 是否使用 GraphicsMagick
*/
private static final boolean IS_USE_GRAPHICS_MAGICK = true;
/**
* ImageMagick安裝路徑,windows下使用
*/
private static final String IMAGE_MAGICK_PATH = "D:\\software\\ImageMagick-6.2.7-Q8";
/**
* gm 命令所在目錄
*/
private static final String GRAPHICS_MAGICK_PATH = "/usr/local/bin";
/**
* 水印圖片路徑
*/
private static final String watermarkImagePath = "/Users/gary/Documents/Job/ImageProcessTool/Im4java/Linux_logo.jpg";
/**
* 水印圖片
*/
private static Image watermarkImage = null;
static {
try {
watermarkImage = ImageIO.read(new File(watermarkImagePath));
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 命令型別
*
*/
private enum CommandType {
convert("轉換處理"), identify("圖片資訊"), compositecmd("圖片合成");
private String name;
CommandType(String name) {
this.name = name;
}
}
/**
* 查詢圖片的基本資訊:格式,質量,寬度,高度
* <p>
* gm identify -format %w,%h,%d/%f,%Q,%b,%e /Users/gary/Documents/999999999/10005582/1.jpg
* <p>
*
* @param imagePath
* @return
*/
public static Map<String, String> getImageInfo(String imagePath) {
long startTime = System.currentTimeMillis();
Map<String, String> imageInfo = new HashMap<>();
try {
IMOperation op = new IMOperation();
op.format("%w,%h,%d/%f,%Q,%b,%e");
op.addImage();
ImageCommand identifyCmd = getImageCommand(CommandType.identify);
ArrayListOutputConsumer output = new ArrayListOutputConsumer();
identifyCmd.setOutputConsumer(output);
identifyCmd.run(op, imagePath);
ArrayList<String> cmdOutput = output.getOutput();
String[] result = cmdOutput.get(0).split(",");
if (result.length == 6) {
imageInfo.put(IMAGE_WIDTH, result[0]);
imageInfo.put(IMAGE_HEIGHT, result[1]);
imageInfo.put(IMAGE_PATH, result[2]);
imageInfo.put(IMAGE_QUALITY, result[3]);
imageInfo.put(IMAGE_SIZE, result[4]);
imageInfo.put(IMAGE_SUFFIX, result[5]);
}
} catch (Exception e) {
// e.printStackTrace();
logger.error("圖片工具獲取圖片基本資訊異常" + e.getMessage(), e);
}
long endTime = System.currentTimeMillis();
// logger.info("take time: " + (endTime - startTime));
return imageInfo;
}
/**
* 獲取 ImageCommand
*
* @param command 命令型別
* @return
*/
private static ImageCommand getImageCommand(CommandType command) {
ImageCommand cmd = null;
switch (command) {
case convert:
cmd = new ConvertCmd(IS_USE_GRAPHICS_MAGICK);
break;
case identify:
cmd = new IdentifyCmd(IS_USE_GRAPHICS_MAGICK);
break;
case compositecmd:
cmd = new CompositeCmd(IS_USE_GRAPHICS_MAGICK);
break;
}
if (cmd != null && System.getProperty("os.name").toLowerCase().indexOf("windows") == -1) {
cmd.setSearchPath(IS_USE_GRAPHICS_MAGICK ? GRAPHICS_MAGICK_PATH : IMAGE_MAGICK_PATH);
}
return cmd;
}
}
上面的程式碼中要注意幾個問題:
- 獲取 ImageCommand時,在new ConvertCmd(true),引數要填true,不填的預設使用的是ImageMagick,引數為true時,才會使用grapicmagick的命令。
- 獲取 ImageCommand 後,要設定命令的搜尋路徑,有時可能會不穩定找不到gm命令,例如 cmd.setSearchPath(“/usr/local/bin”); (gm 命令在該路徑下)
獲取圖片資訊的命令中有個引數 -format ,該引數可取的值如下。
%b file size of image read in
%c comment property
%d directory component of path
%e filename extension or suffix
%f filename (including suffix)
%g layer canvas page geometry ( = %Wx%H%X%Y )
%h current image height in pixels
%i image filename (note: becomes output filename for "info:")
%k number of unique colors
%l label property
%m image file format (file magic)
%n exact number of images in current image sequence
%o output filename (used for delegates)
%p index of image in current image list
%q quantum depth (compile-time constant)
%r image class and colorspace
%s scene number (from input unless re-assigned)
%t filename without directory or extension (suffix)
%u unique temporary filename (used for delegates)
%w current width in pixels
%x x resolution (density)
%y y resolution (density)
%z image depth (as read in unless modified, image save depth)
%A image transparency channel enabled (true/false)
%C image compression type
%D image dispose method
%G image size ( = %wx%h )
%H page (canvas) height
%M Magick filename (original file exactly as given, including read mods)
%O page (canvas) offset ( = %X%Y )
%P page (canvas) size ( = %Wx%H )
%Q image compression quality ( 0 = default )
%S ?? scenes ??
%T image time delay
%W page (canvas) width
%X page (canvas) x offset (including sign)
%Y page (canvas) y offset (including sign)
%Z unique filename (used for delegates)
%@ bounding box
%# signature
%% a percent sign
\n newline
\r carriage return
壓縮圖片質量
/**
* 圖片壓縮
* <p>
* 拼裝命令示例: gm convert -quality 80 /apps/watch.jpg /apps/watch_compress.jpg
*
* @param srcImagePath
* @param destImagePath
* @param quality
* @throws Exception
*/
public static void compressImage(String srcImagePath, String destImagePath, double quality) throws Exception {
IMOperation op = new IMOperation();
op.quality(quality);
op.addImage();
op.addImage();
ImageCommand cmd = getImageCommand(CommandType.convert);
cmd.run(op, srcImagePath, destImagePath);
}
裁剪圖片
/**
* 裁剪圖片
*
* @param imagePath 源圖片路徑
* @param newPath 處理後圖片路徑
* @param x 起始X座標
* @param y 起始Y座標
* @param width 裁剪寬度
* @param height 裁剪高度
* @return 返回true說明裁剪成功, 否則失敗
*/
public static boolean cutImage(String imagePath, String newPath, int x, int y, int width, int height) {
boolean flag = false;
try {
IMOperation op = new IMOperation();
op.addImage(imagePath);
/** width:裁剪的寬度 * height:裁剪的高度 * x:裁剪的橫座標 * y:裁剪縱座標 */
op.crop(width, height, x, y);
op.addImage(newPath);
ConvertCmd convert = new ConvertCmd(true);
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;
}
縮放圖片
/**
* 根據尺寸縮放圖片[等比例縮放:引數height為null,按寬度縮放比例縮放;引數width為null,按高度縮放比例縮放]
*
* @param imagePath 源圖片路徑
* @param newPath 處理後圖片路徑
* @param width 縮放後的圖片寬度
* @param height 縮放後的圖片高度
* @return 返回true說明縮放成功, 否則失敗
*/
public static boolean zoomImage(String imagePath, String newPath, Integer width, Integer height) {
boolean flag;
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(true);
convert.run(op);
flag = true;
} catch (IOException e) {
System.out.println("檔案讀取錯誤!");
flag = false;
} catch (InterruptedException e) {
flag = false;
} catch (IM4JavaException e) {
flag = false;
}
return flag;
}
圖片旋轉
/**
* 圖片旋轉(順時針旋轉)
* 拼裝命令示例: gm convert -rotate 90 /apps/watch.jpg /apps/watch_compress.jpg
*
* @param imagePath 源圖片路徑
* @param newPath 處理後圖片路徑
* @param degree 旋轉角度
*/
public static boolean rotate(String imagePath, String newPath, double degree) {
boolean flag;
try {
// 1.將角度轉換到0-360度之間
degree = degree % 360;
if (degree <= 0) {
degree = 360 + degree;
}
IMOperation op = new IMOperation();
op.rotate(degree);
op.addImage(imagePath);
op.addImage(newPath);
ConvertCmd cmd = new ConvertCmd(true);
cmd.run(op);
flag = true;
} catch (Exception e) {
flag = false;
System.out.println("圖片旋轉失敗!");
}
return flag;
}
新增文字水印
/**
* 文字水印
*
* @param srcImagePath 源圖片路徑
* @param destImagePath 目標圖片路徑
* @param content 文字內容(不支援漢字)
* @throws Exception
*/
public static void addTextWatermark(String srcImagePath, String destImagePath, String content) throws Exception {
IMOperation op = new IMOperation();
op.font("ArialBold");
// 文字方位-東南
op.gravity("southeast");
// 文字資訊
op.pointsize(60).fill("#F2F2F2").draw("text 10,10 " + content);
// 原圖
op.addImage(srcImagePath);
// 目標
op.addImage(destImagePath);
ImageCommand cmd = getImageCommand(CommandType.convert);
cmd.run(op);
}
新增文字前要安裝文字包,或直接指向 ttf 文字格式檔案上。
OSX 安裝
brew install ghostscript
新增中文水印會亂碼,待解決。
新增圖片水印
/**
* 圖片水印
*
* @param srcImagePath 源圖片路徑
* @param destImagePath 目標圖片路徑
* @param dissolve 透明度(0-100)
* @throws Exception
*/
public static void addImgWatermark(String srcImagePath, String destImagePath, Integer dissolve) throws Exception {
// 原始圖片資訊
BufferedImage buffimg = ImageIO.read(new File(srcImagePath));
int w = buffimg.getWidth();
int h = buffimg.getHeight();
IMOperation op = new IMOperation();
// 水印圖片位置
op.geometry(watermarkImage.getWidth(null), watermarkImage.getHeight(null),
w - watermarkImage.getWidth(null) - 10, h - watermarkImage.getHeight(null) - 10);
// 水印透明度
op.dissolve(dissolve);
// 水印
op.addImage(watermarkImagePath);
// 原圖
op.addImage(srcImagePath);
// 目標
op.addImage(destImagePath);
ImageCommand cmd = getImageCommand(CommandType.compositecmd);
cmd.run(op);
}
參考資料
相關文章
- Laravel 使用 Intervention/image 處理圖片Laravel
- webpack圖片處理Web
- Thumbnailator處理圖片AI
- iOS 圖片處理iOS
- 圖片上傳及圖片處理
- VUE例項:使用 CSS Filter 處理圖片VueCSSFilter
- 【YLCircleImageView】圖片處理View
- 002.00 圖片處理
- 圖片處理--羽化特效特效
- SwiftUI Image 圖片處理SwiftUI
- DDGScreenShot —iOS 圖片處理--多圖片拼接 (swift)iOSSwift
- Linux圖片處理 -- ddjvu和convert命令Linux
- Swift使用SDWebImage處理遠端圖片資源SwiftWeb
- 處理圖片流資料
- Python批量處理圖片Python
- java 圖片水印處理類Java
- JavaScript WebGL 圖片透明處理JavaScriptWeb
- Golang 圖片處理 — image 庫Golang
- webpack(6)webpack處理圖片Web
- java thumbnailator 做圖片處理JavaAI
- photoshop常用圖片處理技巧
- webpack 圖片處理 loaderWeb
- OpenCv--圖片處理操作OpenCV
- SwiftUI圖片處理(縮放、拼圖)SwiftUI
- Android中OpenGL濾鏡和RenderScript圖片處理Android
- 圖片處理擴充套件 Grafika 的簡單使用套件
- 線上PS如何處理圖片 怎麼使用線上PS
- android圖片處理,讓圖片變成圓形Android
- 如何處理 Web 圖片優化?Web優化
- 分享一個圖片處理類
- Mac raw圖片處理軟體Mac
- 走近webpack(3)–圖片的處理Web
- Photoshop類圖片處理軟體
- opencv-圖片馬賽克處理OpenCV
- Android圖片處理(Matrix,ColorMatrix)AndroidColorMatrix
- CGContextRef處理圓形圖片GCContext
- Android 圖片快取處理Android快取
- android 圓角圖片 處理Android