对JMagick的一个简单封装
2010-08-12 00:28
281 查看
最近需要给图片加上社区的水印,也需要对用户上传的图片进行压缩和裁剪。Google之,最后选中ImageMagick开源库。ImageMagick提供一个通过JNI调用的Java接口JMagick。虽然不能提供所有ImageMagick的接口,但已经很不错了。
JMagick在Windows下配置很简单,在Linux上配置有一些复杂,主要是依赖库的安装配置。感兴趣的可以查阅相关的资料。注意安装时ImageMagick和JMagick的版本要匹配。
封装的代码如下,基于网络上的代码改动而成,测试通过。
可以写个简单的测试
运行可能会报无法获得文件句柄的错误,请仔细检查图片的路径。
2010-08-1200:26:29
JMagick在Windows下配置很简单,在Linux上配置有一些复杂,主要是依赖库的安装配置。感兴趣的可以查阅相关的资料。注意安装时ImageMagick和JMagick的版本要匹配。
封装的代码如下,基于网络上的代码改动而成,测试通过。
import java.awt.Dimension; import java.awt.Point; import java.awt.Rectangle; import java.io.File; import magick.CompositeOperator; import magick.CompressionType; import magick.DrawInfo; import magick.ImageInfo; import magick.MagickException; import magick.MagickImage; import magick.PixelPacket; import magick.PreviewType; public class JMagicjWrapper { private static final String[] Type = { ".JPG", ".JPEG", ".BMP", ".GIF", ".PNG" }; public static boolean checkType(String path){ for (int i = 0; i < Type.length; i++) { if (path.toUpperCase().endsWith(Type[i])) { return true; }else { continue; } } return false; } /**改变图片大小 * @param filePath 原图片位置 * toPath 新图片位置 * width 新图片的宽度 * height 新图片的高度 * @return * @throw * @author sulliy@sina.com 2010-8-11 */ public static void imageResize(String filePath, String toPath, int width, int height) throws MagickException { ImageInfo info = null; MagickImage image = null; Dimension imageDim = null; MagickImage scaled = null; if (!checkType(filePath) || !checkType(toPath)) { return; } try { info = new ImageInfo(filePath); image = new MagickImage(info); imageDim = image.getDimension(); if (width <= 0 || height <= 0) { height = 120; width = 120; } scaled = image.scaleImage(width, height); scaled.setFileName(toPath); scaled.writeImage(info); } finally { if (scaled != null) { scaled.destroyImages(); } } } /**创建图片水印 * @param filePath 源文件路径 * toImg 生成文件位置 * logoPath logo路径 * pos logo在源图片中的相对位置,以像素点为单位 * @return * @throw MagickException * @author sulliy@sina.com 2010-8-11 */ public static void createWaterPrintByImg(String filePath, String toImg, String logoPath, Point pos) throws MagickException { if (!checkType(filePath) || !checkType(toImg) || !checkType(logoPath)) { return; } ImageInfo info = new ImageInfo(); MagickImage fImage = null; MagickImage sImage = null; MagickImage fLogo = null; MagickImage sLogo = null; Dimension imageDim = null; Dimension logoDim = null; try { fImage = new MagickImage(new ImageInfo(filePath)); imageDim = fImage.getDimension(); int width = imageDim.width; int height = imageDim.height; sImage = fImage.scaleImage(width, height); fLogo = new MagickImage(new ImageInfo(logoPath)); //fLogo.transparentImage(PixelPacket.queryColorDatabase("white"), 65535); //设置背景色 logoDim = fLogo.getDimension(); int lw = logoDim.width; int lh = logoDim.height; //默认或者参数出错时,LOGO放在右下角 if (width <= (int)pos.getX() || height <= (int)pos.getY()) { pos.setLocation(width - lw, height - lh); } sLogo = fLogo.scaleImage(lw, lh); sImage.compositeImage(CompositeOperator.AtopCompositeOp, sLogo, (int)pos.getX(), (int)pos.getY()); sImage.setFileName(toImg); sImage.writeImage(info); } finally { if (sImage != null) { sImage.destroyImages(); } } } /**创建文字水印 * @param filePath 源文件路径 * toImg 生成文件位置 * text 水印文本 * pos logo在源图片中的相对位置,以像素点为单位 * pointSize 用于设置点阵大小 * @return * @throw MagickException * @author sulliy@sina.com 2010-8-11 */ public static void createWaterPrintByText(String filePath, String toImg, String text , Point pos, int pointSize) throws MagickException { if (!checkType(filePath) || !checkType(toImg)) { return; } if (null == text || "".equals(text)) { text = "sulliy@sina.com"; } ImageInfo info = new ImageInfo(filePath); if (filePath.toUpperCase().endsWith("JPG") || filePath.toUpperCase().endsWith("JPEG")) { info.setCompression(CompressionType.JPEGCompression); // 压缩类别为JPEG格式 info.setPreviewType(PreviewType.JPEGPreview); // 预览格式为JPEG格式 info.setQuality(95); } MagickImage aImage = new MagickImage(info); Dimension imageDim = aImage.getDimension(); int width = imageDim.width; int height = imageDim.height; if (width <= (int)pos.getX() || height <= (int)pos.getY()) { pos.setLocation(0, 0); } int a = 0; int b = 0; String[] as = text.split(""); for (String string : as) { if (string.matches("[/u4E00-/u9FA5]")) { a++; } if (string.matches("[a-zA-Z0-9]")) { b++; } } int tl = a * 12 + b * 6 ;//字符长度 MagickImage scaled = aImage.scaleImage(width, height); if (width > tl && height > 5) { DrawInfo aInfo = new DrawInfo(info); aInfo.setFill(PixelPacket.queryColorDatabase("white")); aInfo.setUnderColor(new PixelPacket(65535, 65535, 65535, 65535));//设置为透明颜色 aInfo.setPointsize(pointSize); // 解决中文乱码问题,自己可以去随意定义个自己喜欢字体,我在这用的微软雅黑 String fontPath = "C:/WINDOWS/Fonts/MSIMHEI.TTF"; // String fontPath = "/usr/maindata/MSYH.TTF"; aInfo.setFont(fontPath); aInfo.setTextAntialias(true); aInfo.setOpacity(0);//透明度 aInfo.setText(text); aInfo.setGeometry("+" + ((int)pos.getX() + "+" + (int)pos.getY())); scaled.annotateImage(aInfo); } scaled.setFileName(toImg); scaled.writeImage(info); scaled.destroyImages(); } /**切取图片 * @param imgPath 原图路径 * toPath 生成文件位置 * w 左上位置横坐标 * h 左上位置竖坐标 * x 右下位置横坐标 * y 右下位置竖坐标 * @return * @throw MagickException * @author sulliy@sina.com 2010-8-11 */ public static void cutImg(String imgPath, String toPath, int w, int h, int x, int y) throws MagickException { ImageInfo infoS = null; MagickImage image = null; MagickImage cropped = null; Rectangle rect = null; try { infoS = new ImageInfo(imgPath); image = new MagickImage(infoS); rect = new Rectangle(x, y, w, h); cropped = image.cropImage(rect); cropped.setFileName(toPath); cropped.writeImage(infoS); } finally { if (cropped != null) { cropped.destroyImages(); } } } /**删除图片文件 * @param src 图片位置 * @return * @throw * @author sulliy@sina.com 2010-8-11 */ public static boolean removeFile(String src) throws SecurityException{ try { if (!checkType(src)) { return false; } File file = new File(src); return file.delete(); } catch (Exception e) { e.printStackTrace(); return false; } } }
可以写个简单的测试
import java.awt.Point; import magick.MagickException; public class JMagicjWrapperTest { public static void main(String[] args) throws MagickException{ //test for function imageResize JMagicjWrapper.imageResize("pics.jpg", "reSize20x30.png", 20, 30); JMagicjWrapper.imageResize("pics.jpg", "reSize250x200.jpeg", 250, 200); JMagicjWrapper.imageResize("pics.jpg", "reSize50x50.jpg", 50, 50); JMagicjWrapper.imageResize("pics.jpg", "reSize120x120.bmp", 120, 120); JMagicjWrapper.imageResize("pics.jpg", "reSize.tif", 20, 30);//not create file //test for function createWaterPrintByImg JMagicjWrapper.createWaterPrintByImg("pics.jpg", "wpl.gif", "logo.jpg", new Point(100,100)); JMagicjWrapper.imageResize("wpl.gif", "logo250x200.gif", 250, 200); //Because file "wpl.gif" may not be release, the later function cause a error, can not open file handle. //JMagicjWrapper.createWaterPrintByImg("pics.jpg", "wpl.gif", "logoFull.jpg", new Point(1680,1050));//not create file //JMagicjWrapper.createWaterPrintByImg("pics.jpg", "wpl.gif", "logoExt.jpg", new Point(2000,1000));//not create file //test for function createWaterPrintByText //This function can not handle Chinese Character, I'll continue to takle the issue JMagicjWrapper.createWaterPrintByText("pics1.jpg", "wpt.gif", "For Test", new Point(300,300), 100); } }
运行可能会报无法获得文件句柄的错误,请仔细检查图片的路径。
2010-08-1200:26:29
相关文章推荐
- 关于轻量级数据库SQLite一个简单的SQLiteHelper访问数据库封装类
- 简单封装的一个彩色进度条【原创】
- 一个mongodb的helper,封装了一些简单常用的功能
- 一个简单封装存储二维数据表的类
- 一个简单封装好的item
- 封装一个简单的同步Ajax函数
- 一个简单的串行协议的封装
- 分享一个性能统计的简单封装类
- 一个简单的类似通讯录的封装代码
- 编译BaseClasses,该工程是对dshow的一个简单封装, 据说用它开发比较方便。
- 封装一个简单实用的朋友圈
- C++封装一个简单的线程类
- Afinal 是一个android的sqlite orm 和 ioc 框架。同时封装了android中的http框架,使其更加简单易用
- 自己封装的一个简单组件:文字标签+文本框
- 一个简单封装好的item
- java 导出excel封装了一个简单的导出方法。
- Python一个简单的数据库类封装
- 闲来无事,将自己收集到的工具类封装了下,做了一个lib,写了个简单的mvp,初学者可以看看
- C++封装一个简单的线程类
- 无缝滚动的一个简单封装