您的位置:首页 > 其它

对JMagick的一个简单封装

2010-08-12 00:28 281 查看
最近需要给图片加上社区的水印,也需要对用户上传的图片进行压缩和裁剪。Google之,最后选中ImageMagick开源库。ImageMagick提供一个通过JNI调用的Java接口JMagick。虽然不能提供所有ImageMagick的接口,但已经很不错了。

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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: