赞
踩
ImageMagick 官网 http://www.imagemagick.org/script/index.php
JMagick 官网 http://www.jmagick.org/index.html (官网的源码svn:https://jmagick.svn.sourceforge.net/svnroot/jmagick)
ImageMagick 是一个功能很强的图片处理程序。可应用在多种操作系统平台上。
Jmagick通过jni操作ImageMagick。
Javashop支持通过ImageMagick生成图片缩略图,但需要系统中配置好 ImageMagick。
确认已经安装了zlib、freetype、libpng和jpeg-6b等lib的开发包,可以用rpm-aq查询,例如,你应该检查是否已经安装如下rpm包:
rpm –qa |grep libpng
rpm –qa |grep libpng-devel
rpm –qa |grep libjpeg
rpm –qa |grep gd-devel
如果你希望支持tiff格式,还应该检查
rpm –qa |grep libtiff
tar xzvf ImageMagick- 6.4.0.tar.gz
./configure --prefix=/opt/ImageMagick --enable-share--enable-static
Make
make install
使用convert 看看是否可以转换文件
测试:convert-geometry 600x200 star.jpg star_small.gif
tar xzvf jmagick-6.4.0.tar.gz
./configure --prefix=/opt/JMagick--with-magick-home=/opt/ImageMagick
--enable-share --enable-static --with-java-home=/usr/java/jdk6
make all
make install
vi /etc/profile
加入:
export PATH=$PATH:/opt/ImageMagick/bin
export LD_LIBRARY_PATH=:/opt/JMagick/lib:/opt/ImageMagick/lib
exportDYLD_LIBRARY_PATH=:/opt/JMagick/lib:/opt/ImageMagick/lib
export CLASSPATH=$CLASSPATH:/opt/JMagick/lib
如果要在Tomcat中运行,需要再运行时加入参数: -Djmagick.systemclassloader=no
或者在程序中写入:System.setProperty("jmagick.systemclassloader","no")。
=========================================================================
Jmagick的安装和使用
ImageMagick 是一个用来创建、编辑、合成图片的软件。它可以读取、转换、写入多种格式的图片。图片切割、颜色替换、各种效果的应用,图片的旋转、组合,文本,直线, 多边形,椭圆,曲线,附加到图片伸展旋转。ImageMagick是免费软件:全部源码开放,可以自由使用,复制,修改,发布。支持大多数的操作系统。
1.对用户上传图片进行缩放
对于用户自己上传的图片不能简单的 用css限制大小,因为这样每次加载图片时候还是会加载整幅大图。占用多余的宽带,并且影响页面加载速度。应该根据实际显示需要进行缩放。比如我想要用户 相册里的图片大小不能超过500x300:
用ImageMagick处理起来很简单
convert -resize "500x300>" input.jpg output.jpg #如果图片比500x300小就保持原样,以防小图片被放大失真。
2.生成不同比例缩略图
一般相册等应用,都会提供缩略图和预览图,这些缩略图同样不能简单的用css来限制大小,要为每个图片生成不同比例的预览图。
3.去除多余信息
Exif信息是数码相机在拍摄过程中采集的一系列信息,这些信息放置在我们熟知的jpg文件的头部,也就是说Exif信息是镶嵌在JPEG图像文件格式内的一组拍摄参数,主要包括摄影时的光圈、快门、ISO、日期时间等各种与当时摄影条件相关的讯息,相机品牌型号,色彩编码,拍摄时录制的声音以及全球定位系统(GPS)等信息。简单的说,它就好像是傻瓜相机的日期打印功能一样,只不过Exif信息所记录的资讯更为详尽和完备。不过,具有Exif信息的 JPEG图像文件要比普通的JPEG文件略大一点。还有就是像PS这种软件处理过的图片会有“program comments”。如果不是专业的摄影类网站,这些信息是没有用的,可以去掉:
convert -strip input.jpg output.jpg
4.调节压缩比
大多时候,我们的网站并不需要那么清晰的图片,适量调节JPG图片的压缩比会减少图片大小,肉眼并不会分辨出质量被压缩后的图片。通常75%是最佳比例。
convert -quality 75% input.jpg output.jpg
上面几个步骤可以一次搞定:
convert -resize "500x300" -strip -quality 75% input.jpg output.jpg
上面说的都是针对JPG格式的处理方式,下面说一下BMP,GIF,PNG等格式的处理。
对于BMP直接转成JPG就可以了。再按照上面的方式处理。
而GIF和PNG貌似有些特殊。GIF的一些特性(动画效果,透明等)是 JPG没有的,可以根据实际情况选择转或不转,如果转换成jpg,取第一帧只需要这样:
convert -format jpg input.gif input.jpg
一些基本使用方法的代码,具体大家可以参考官方给的源码,那里比较详细:
- package org.wsr.util;
-
- 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 {
-
- 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("f://1.jpg", "f://4.jpg", "f://watermark.gif", new Point(0,0));
- //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);
- }
-
- 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();
- 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));
- logoDim = fLogo.getDimension();
- int lw = logoDim.width;
- int lh = logoDim.height;
- sLogo = fLogo.scaleImage(lw, lh);
-
- //开始打水印,从左上角开始;如果到右边界则重新开始一行的打印(x=0,y=y+h)
- int startX = 0;
- int startY = 0;
- do {
- sImage.compositeImage(CompositeOperator.AtopCompositeOp, sLogo,
- startX, startY);
- startX += (logoDim.width + 60);
- if (startX >= width){
- startY += logoDim.height * 2;
- startX = 0;
- }
- } while(startY <= height);
-
- sImage.setFileName(toImg);
- sImage.writeImage(info);
- } finally {
- if (fImage != null) {
- fImage.destroyImages();
- }
- if (sImage != null) {
- sImage.destroyImages();
- }
- if (fLogo != null) {
- fLogo.destroyImages();
- }
- if (sLogo != null) {
- sLogo.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;
- }
- }
-
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。