Chinaunix首页 | 论坛 | 博客
  • 博客访问: 613056
  • 博文数量: 152
  • 博客积分: 2684
  • 博客等级: 少校
  • 技术积分: 1126
  • 用 户 组: 普通用户
  • 注册时间: 2010-10-29 11:03
文章分类
文章存档

2012年(6)

2011年(96)

2010年(50)

分类: Java

2010-10-29 15:17:15

近期有使用到图片的压缩处理,由于在之前用Java 处理时,在低像素的情况下,Java 处理的效果确实很差,然后尝试了用网上推荐的免费开源的第三方软件,利用Java 的jni 调用dll 文件进行处理,效果还可以。在此记录下,方便以后继续积累。

 

1、纯Java 类处理图片代码

Java代码 
  1. /** 
  2.      * 转换图片大小,不变形 
  3.      *  
  4.      * @param img 
  5.      *            图片文件 
  6.      * @param width 
  7.      *            图片宽 
  8.      * @param height 
  9.      *            图片高 
  10.      */  
  11.     public static void changeImge(File img, int width, int height) {  
  12.         try {  
  13.             Image image = ImageIO.read(img);  
  14.             //图片尺寸的大小处理,如果长宽都小于规定大小,则返回,如果有一个大于规定大小,则等比例缩放  
  15.             int srcH = image.getHeight(null);  
  16.             int srcW = image.getWidth(null);  
  17.             if (srcH <= height && srcW <= width) {  
  18.                 return;  
  19.             }  
  20.             int tmpH = width;  
  21.             int tmpW = height;  
  22.             //在长度和宽度都做了限制,不能超过设定值  
  23.             while (srcH > height || srcW > width) {  
  24.                 if(srcW > width) {  
  25.                     tmpH = srcH * width / srcW;  
  26.                     srcH = tmpH;  
  27.                     srcW=width;   
  28.                 }  
  29.                 if(srcH > height) {  
  30.                     tmpW = srcW * height / srcH;  
  31.                     srcW = tmpW;  
  32.                     srcH=height;  
  33.                 }  
  34.             }  
  35.   
  36.             BufferedImage bufferedImage = new BufferedImage(srcW, srcH,  
  37.                     BufferedImage.TYPE_3BYTE_BGR);  
  38.   
  39.             bufferedImage.getGraphics().drawImage(  
  40.                     image.getScaledInstance(srcW, srcH, Image.SCALE_SMOOTH), 0,  
  41.                     0, srcW, srcH, null);  
  42.   
  43.             FileOutputStream fos = new FileOutputStream(img);  
  44.   
  45.             JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(fos);  
  46.   
  47.             encoder.encode(bufferedImage);  
  48.             fos.close();  
  49.             // System.out.println("转换成功...");  
  50.         } catch (IOException e) {  
  51.             e.printStackTrace();  
  52.             throw new IllegalStateException("图片转换出错!", e);  
  53.         }  
  54.   
  55.     }  

 

2、使用Jmagick 辅助

(参考了以下网站:)

Html代码 
  1. (1)使用的windows下的jmagick-win-6.3.9-q16.zip 地址是:
  2.   
  3. (2)doc对应的api地址:
  4.   
  5. (3)安装imagemagick,官方网站:http://www.imagemagick.org/  
  6.   
  7. 我使用的是:imagemagick-6.4.6-4-q16-windows-dll.exe :点击下载  
  8.   
  9. (4) 安装imagemagick-6.4.6-4-q16-windows-dll.exe,将 安装目录下(按自己所安装的目录找) 下的所有dll文件 copy 到系统盘下的 “c:\windows\system32\”文件夹里  
  10.   
  11. (5) 配置环境变量  
  12. 再环境变量path里添加新的值 “c:\program files\imagemagick-6.4.6-4-q16“使用ide可以不用配置  
  13.   
  14. (6)解压jmagick-win-6.3.9-q16.zip  
  15. 将 jmagick.dll 复制到系统盘下的 “c:\windows\system32\”文件夹里 和 复制到jdk的bin(例“d:\jdk6\bin”)文件里各一份  
  16. 将 jmagick.jar 复制到tomcat下的lib文件夹里 和 所使用项目的web-inf下lib文件里 各一份  
  17.   
  18. (7)web应用如果部署到tomcat下,那么最好在catalina.bat文件中改变如下设置  
  19. set java_opts=%java_opts% -xms256m -xmx768m -xx:maxpermsize=128m – djava.util.logging.manager=org.apache.juli.classloaderlogmanager – djava.util.logging.config.file=”${catalina.base}\conf\logging.properties”  
  20. 避免heap溢出的问题,参数看你自己的机器而定。( -xms256m -xmx768m -xx:maxpermsize=128m )   
  21.   
  22. (8)还要注意如果部署到web应用,你在使用的class里面需要  
  23. system.setproperty(“jmagick.systemclassloader”,”no”);  
  24. 要不然会报出unsatisfiedlinkerror: no jmagick in java.library.path.  

 

工具类:

Java代码 
  1. import java.awt.Dimension;  
  2. import java.awt.Rectangle;  
  3. import java.text.SimpleDateFormat;  
  4. import java.util.Date;     
  5. import magick.CompositeOperator;  
  6. import magick.CompressionType;  
  7. import magick.DrawInfo;  
  8. import magick.ImageInfo;  
  9. import magick.MagickException;  
  10. import magick.MagickImage;  
  11. import magick.PixelPacket;  
  12. import magick.PreviewType;     
  13.    
  14. public class ImageUtils {     
  15.     static{  
  16.         //不能漏掉这个,不然jmagick.jar的路径找不到  
  17.         System.setProperty("jmagick.systemclassloader","no");  
  18.     }     
  19.     /** 
  20.      * 压缩图片,不变形 
  21.      * @param filePath 源文件路径 
  22.      * @param toPath   缩略图路径 
  23.      * @param width 设定宽 
  24.      * @param height 设定长 
  25.      */  
  26.     public static void changeSize(String filePath, String toPath,int width,int height) throws MagickException{  
  27.         ImageInfo info = null;  
  28.         MagickImage image = null;  
  29.         Dimension imageDim = null;  
  30.         MagickImage scaled = null;  
  31.         try{  
  32.             info = new ImageInfo(filePath);  
  33.             image = new MagickImage(info);  
  34.             imageDim = image.getDimension();  
  35.           //图片尺寸的大小处理,如果长宽都小于规定大小,则返回,如果有一个大于规定大小,则等比例缩放  
  36.             int srcH = imageDim.width;  
  37.             int srcW = imageDim.height;  
  38.             if (srcH <= height && srcW <= width) {  
  39.                 return;  
  40.             }  
  41.             int tmpH = width;  
  42.             int tmpW = height;  
  43.             //在长度和宽度都做了限制,不能超过设定值  
  44.             while (srcH > height || srcW > width) {  
  45.                 if(srcW > width) {  
  46.                     tmpH = srcH * width / srcW;  
  47.                     srcH = tmpH;  
  48.                     srcW=width;   
  49.                 }  
  50.                 if(srcH > height) {  
  51.                     tmpW = srcW * height / srcH;  
  52.                     srcW = tmpW;  
  53.                     srcH=height;  
  54.                 }  
  55.             }  
  56.             scaled = image.scaleImage(srcW, srcH);//小图片文件的大小.  
  57.             scaled.setFileName(toPath);  
  58.             scaled.writeImage(info);  
  59.         }finally{  
  60.             if(scaled != null){  
  61.                 scaled.destroyImages();  
  62.             }  
  63.         }  
  64.     }     
  65.    
  66.     /** 
  67.      * 水印(图片logo) 
  68.      * @param filePath  源文件路径 
  69.      * @param toImg     修改图路径 
  70.      * @param logoPath  logo图路径 
  71.      * @throws MagickException 
  72.      */  
  73.     public static void initLogoImg(String filePath, String toImg, String logoPath) throws MagickException {  
  74.         ImageInfo info = new ImageInfo();  
  75.         MagickImage fImage = null;  
  76.         MagickImage sImage = null;  
  77.         MagickImage fLogo = null;  
  78.         MagickImage sLogo = null;  
  79.         Dimension imageDim = null;  
  80.         Dimension logoDim = null;  
  81.         try {  
  82.             fImage = new MagickImage(new ImageInfo(filePath));  
  83.             imageDim = fImage.getDimension();  
  84.             int width = imageDim.width;  
  85.             int height = imageDim.height;  
  86.             if (width > 660) {  
  87.                 height = 660 * height / width;  
  88.                 width = 660;  
  89.             }  
  90.             sImage = fImage.scaleImage(width, height);     
  91.    
  92.             fLogo = new MagickImage(new ImageInfo(logoPath));  
  93.             logoDim = fLogo.getDimension();  
  94.             int lw = width / 8;  
  95.             int lh = logoDim.height * lw / logoDim.width;  
  96.             sLogo = fLogo.scaleImage(lw, lh);     
  97.    
  98.             sImage.compositeImage(CompositeOperator.AtopCompositeOp, sLogo,  width-(lw + lh/10), height-(lh + lh/10));  
  99.             sImage.setFileName(toImg);  
  100.             sImage.writeImage(info);  
  101.         } finally {  
  102.             if(sImage != null){  
  103.                 sImage.destroyImages();  
  104.             }  
  105.         }  
  106.     }     
  107.    
  108.     /** 
  109.      * 水印(文字) 
  110.      * @param filePath 源文件路径 
  111.      * @param toImg    修改图路径 
  112.      * @param text     名字(文字内容自己随意) 
  113.      * @throws MagickException 
  114.      */  
  115.     public static void initTextToImg(String filePath, String toImg,  String text) throws MagickException{  
  116.             ImageInfo info = new ImageInfo(filePath);  
  117.             if (filePath.toUpperCase().endsWith("JPG") || filePath.toUpperCase().endsWith("JPEG")) {  
  118.                 info.setCompression(CompressionType.JPEGCompression); //压缩类别为JPEG格式  
  119.                 info.setPreviewType(PreviewType.JPEGPreview); //预览格式为JPEG格式  
  120.                 info.setQuality(95);  
  121.             }  
  122.             MagickImage aImage = new MagickImage(info);  
  123.             Dimension imageDim = aImage.getDimension();  
  124.             int wideth = imageDim.width;  
  125.             int height = imageDim.height;  
  126.             if (wideth > 660) {  
  127.                 height = 660 * height / wideth;  
  128.                 wideth = 660;  
  129.             }  
  130.             int a = 0;  
  131.             int b = 0;  
  132.             String[] as = text.split("");  
  133.             for (String string : as) {  
  134.                 if(string.matches("[\u4E00-\u9FA5]")){  
  135.                     a++;  
  136.                 }  
  137.                 if(string.matches("[a-zA-Z0-9]")){  
  138.                     b++;  
  139.                 }  
  140.             }  
  141.             int tl = a*12 + b*6 + 300;  
  142.             MagickImage scaled = aImage.scaleImage(wideth, height);  
  143.             if(wideth > tl && height > 5){  
  144.                 DrawInfo aInfo = new DrawInfo(info);  
  145.                 aInfo.setFill(PixelPacket.queryColorDatabase("white"));  
  146.                 aInfo.setUnderColor(new PixelPacket(0,0,0,100));  
  147.                 aInfo.setPointsize(12);  
  148.                 //解决中文乱码问题,自己可以去随意定义个自己喜欢字体,对于移植有点问题,所以暂且注释  
  149.            //     String fontPath = "C:/WINDOWS/Fonts/MSYH.TTF";  
  150.             //    aInfo.setFont(fontPath);  
  151.                 aInfo.setTextAntialias(true);  
  152.                 aInfo.setOpacity(0);  
  153.                 aInfo.setText(" " + text + "于 " + new SimpleDateFormat("yyyy-MM-dd").format(new Date()) + " 上传于XXXX网,版权归作者所有!");  
  154.                 aInfo.setGeometry("+" + (wideth-tl) + "+" + (height-5));  
  155.                 scaled.annotateImage(aInfo);  
  156.             }  
  157.             scaled.setFileName(toImg);  
  158.             scaled.writeImage(info);  
  159.             scaled.destroyImages();  
  160.     }     
  161.    
  162.     /** 
  163.      * 切图 
  164.      * @param imgPath 源图路径 
  165.      * @param toPath  修改图路径 
  166.      * @param w  宽度 
  167.      * @param h 高度 
  168.      * @param x 左上角的 X 坐标 
  169.      * @param y 左上角的 Y 坐标 
  170.      * @throws MagickException 
  171.      */  
  172.     public static void cutImg(String imgPath, String toPath, int w, int h, int x, int y) throws MagickException {  
  173.         ImageInfo infoS = null;  
  174.         MagickImage image = null;  
  175.         MagickImage cropped = null;  
  176.         Rectangle rect = null;  
  177.         try {  
  178.             infoS = new ImageInfo(imgPath);  
  179.             image = new MagickImage(infoS);  
  180.             rect = new Rectangle(x, y, w, h);  
  181.             cropped = image.cropImage(rect);  
  182.             cropped.setFileName(toPath);  
  183.             cropped.writeImage(infoS);     
  184.    
  185.         } finally {  
  186.             if (cropped != null) {  
  187.                 cropped.destroyImages();  
  188.             }  
  189.         }  
  190.     }  
  191. }  

 

 原文地址 http://zhxing.javaeye.com/blog/585223

本博文转载于:CS_FB4的博客

阅读(1856) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~