posts - 495,comments - 227,trackbacks - 0

   过去做的项目都是针对企业级应用,第一次开发新闻版块图片上传的功能,需要解决用户上传图片后,按照用户规定的尺寸大小或者按照图片比例,对图片进行压缩。

之前做过图片压缩处理,不过使用的是一个组件,这个组件需要在服务器上进行安装,很不方便。组件的下载地址是:

http://www.imagemagick.org/download/binaries/ImageMagick-6.2.9-4-Q16-windows-dll.exe

    自己试写的工具类,写的时候考虑了几个关键点:

    1、图片格式

    JAVA的API很好,com.sun.image.codec.jpeg.JPEGCodec和com.sun.image.codec.jpeg.JPEGImageEncoder 这两个类基本上自动解决了类型转换的问题,可以正常实现bmp转jpg、png转jpg、gif转jpg但是暂时还没有解决gif转gif的功能。

    2、画面质量的问题

    BufferedImage tag = new BufferedImage((int)newWidth, (int) newHeight, BufferedImage.TYPE_INT_RGB);

    // Image.SCALE_SMOOTH 的缩略算法 生成缩略图片的平滑度的 优先级比速度高 生成的图片质量比较好 但速度慢

    tag.getGraphics().drawImage(img.getScaledInstance(newWidth, newHeight, Image.SCALE_SMOOTH), 0, 0, null);

    3、压缩速度

    测试36MB的bmp图片(8192*6144)压缩成(160*120)的jpg的5KB图片,只需要2-3秒的时间。批量处理100张(1027*768)的bmp图像,转换成(120*80)的jpg图片总共只需要17秒。

    4、根据用户喜好选择压缩模式

    按比例或者按规定尺寸

    //compressPic(大图片路径,生成小图片路径,大图片文件名,生成小图片文名,生成小图片宽度,生成小图片高度,是否等比缩放(默认为true))

 

    以下是源码,如觉得可以更加完善的话,希望大家可以提供点意见!

/**
 *  缩略图实现,将图片(jpg、bmp、png、gif等等)真实的变成想要的大小
 
*/
package com.joewalker.test;

import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import javax.imageio.ImageIO;
import com.sun.image.codec.jpeg.JPEGCodec;
import com.sun.image.codec.jpeg.JPEGImageEncoder;

/*******************************************************************************
 * 缩略图类(通用) 本java类能将jpg、bmp、png、gif图片文件,进行等比或非等比的大小转换。 具体使用方法
 * compressPic(大图片路径,生成小图片路径,大图片文件名,生成小图片文名,生成小图片宽度,生成小图片高度,是否等比缩放(默认为true))
 
*/
 
public class CompressPicDemo { 
     
private File file = null// 文件对象 
     private String inputDir; // 输入图路径
     private String outputDir; // 输出图路径
     private String inputFileName; // 输入图文件名
     private String outputFileName; // 输出图文件名
     private int outputWidth = 100// 默认输出图片宽
     private int outputHeight = 100// 默认输出图片高
     private boolean proportion = true// 是否等比缩放标记(默认为等比缩放)
     public CompressPicDemo() { // 初始化变量
         inputDir = ""
         outputDir 
= ""
         inputFileName 
= ""
         outputFileName 
= ""
         outputWidth 
= 100
         outputHeight 
= 100
     } 
     
public void setInputDir(String inputDir) { 
         
this.inputDir = inputDir; 
     } 
     
public void setOutputDir(String outputDir) { 
         
this.outputDir = outputDir; 
     } 
     
public void setInputFileName(String inputFileName) { 
         
this.inputFileName = inputFileName;
     } 
     
public void setOutputFileName(String outputFileName) { 
         
this.outputFileName = outputFileName; 
     } 
     
public void setOutputWidth(int outputWidth) {
         
this.outputWidth = outputWidth; 
     } 
     
public void setOutputHeight(int outputHeight) { 
         
this.outputHeight = outputHeight; 
     } 
     
public void setWidthAndHeight(int width, int height) { 
         
this.outputWidth = width;
         
this.outputHeight = height; 
     } 
     
     
/* 
      * 获得图片大小 
      * 传入参数 String path :图片路径 
      
*/ 
     
public long getPicSize(String path) { 
         file 
= new File(path); 
         
return file.length(); 
     }
     
     
// 图片处理 
     public String compressPic() { 
         
try { 
             
//获得源文件 
             file = new File(inputDir + inputFileName); 
             
if (!file.exists()) { 
                 
return ""
             } 
             Image img 
= ImageIO.read(file); 
             
// 判断图片格式是否正确 
             if (img.getWidth(null== -1) {
                 System.out.println(
" can't read,retry!" + "<BR>"); 
                 
return "no"
             } 
else { 
                 
int newWidth; int newHeight; 
                 
// 判断是否是等比缩放 
                 if (this.proportion == true) { 
                     
// 为等比缩放计算输出的图片宽度及高度 
                     double rate1 = ((double) img.getWidth(null)) / (double) outputWidth + 0.1
                     
double rate2 = ((double) img.getHeight(null)) / (double) outputHeight + 0.1
                     
// 根据缩放比率大的进行缩放控制 
                     double rate = rate1 > rate2 ? rate1 : rate2; 
                     newWidth 
= (int) (((double) img.getWidth(null)) / rate); 
                     newHeight 
= (int) (((double) img.getHeight(null)) / rate); 
                 } 
else { 
                     newWidth 
= outputWidth; // 输出的图片宽度 
                     newHeight = outputHeight; // 输出的图片高度 
                 } 
                 BufferedImage tag 
= new BufferedImage((int) newWidth, (int) newHeight, BufferedImage.TYPE_INT_RGB); 
                 
                 
/*
                 * Image.SCALE_SMOOTH 的缩略算法 生成缩略图片的平滑度的
                 * 优先级比速度高 生成的图片质量比较好 但速度慢
                 
*/ 
                 tag.getGraphics().drawImage(img.getScaledInstance(newWidth, newHeight, Image.SCALE_SMOOTH), 
00null);
                 FileOutputStream out 
= new FileOutputStream(outputDir + outputFileName);
                 
// JPEGImageEncoder可适用于其他图片类型的转换 
                 JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out); 
                 encoder.encode(tag); 
                 out.close(); 
             } 
         } 
catch (IOException ex) { 
             ex.printStackTrace(); 
         } 
         
return "ok"
    } 
     
public String compressPic (String inputDir, String outputDir, String inputFileName, String outputFileName) { 
         
// 输入图路径 
         this.inputDir = inputDir; 
         
// 输出图路径 
         this.outputDir = outputDir; 
         
// 输入图文件名 
         this.inputFileName = inputFileName; 
         
// 输出图文件名
         this.outputFileName = outputFileName; 
         
return compressPic(); 
     } 
     
public String compressPic(String inputDir, String outputDir, String inputFileName, String outputFileName, int width, int height, boolean gp) { 
         
// 输入图路径 
         this.inputDir = inputDir; 
         
// 输出图路径 
         this.outputDir = outputDir; 
         
// 输入图文件名 
         this.inputFileName = inputFileName; 
         
// 输出图文件名 
         this.outputFileName = outputFileName; 
         
// 设置图片长宽
         setWidthAndHeight(width, height); 
         
// 是否是等比缩放 标记 
         this.proportion = gp; 
         
return compressPic(); 
     } 
     
     
// main测试 
     
// compressPic(大图片路径,生成小图片路径,大图片文件名,生成小图片文名,生成小图片宽度,生成小图片高度,是否等比缩放(默认为true))
     public static void main(String[] arg) { 
         CompressPicDemo mypic 
= new CompressPicDemo(); 
         System.out.println(
"输入的图片大小:" + mypic.getPicSize("e:\\1.jpg")/1024 + "KB"); 
         
int count = 0// 记录全部图片压缩所用时间
         for (int i = 0; i < 100; i++) { 
             
int start = (int) System.currentTimeMillis();    // 开始时间 
             mypic.compressPic("e:\\""e:\\test\\""1.jpg""r1"+i+".jpg"120120true); 
             
int end = (int) System.currentTimeMillis(); // 结束时间 
             int re = end-start; // 但图片生成处理时间 
             count += re; System.out.println("" + (i+1+ "张图片压缩处理使用了: " + re + "毫秒"); 
             System.out.println(
"输出的图片大小:" + mypic.getPicSize("e:\\test\\r1"+i+".jpg")/1024 + "KB"); 
         }
         System.out.println(
"总共用了:" + count + "毫秒"); 
     } 
 }


posted on 2009-08-21 12:02 SIMONE 阅读(9429) 评论(4)  编辑  收藏 所属分类: JAVA

FeedBack:
# re: 图片上传压缩处理(可以正常实现bmp转jpg、png转jpg、gif转jpg,但是暂时还没有解决gif转gif的功能)
2010-07-30 09:42 | 唐晓明 t
您好:请问,如果是c++ 程序如何解决 图片上传和压缩的问题啊,这个是我的邮箱方便告诉我吗?我为这个问题搞了好长时间了,谢谢您了Towusan.tang@pantrateq.com  回复  更多评论
  
# re: 图片上传压缩处理(可以正常实现bmp转jpg、png转jpg、gif转jpg,但是暂时还没有解决gif转gif的功能)
2010-09-19 07:25 | 纽斯丽
不错多谢   回复  更多评论
  
# re: 图片上传压缩处理(可以正常实现bmp转jpg、png转jpg、gif转jpg,但是暂时还没有解决gif转gif的功能)[未登录]
2011-06-02 16:17 | 你好
这是java处理代码,如果jsp得input 标签 type="file"要上传图片,Servlet如何获得这个图片的路径呢?只有file里的完整路径,才可以进行下一步的读取啊。  回复  更多评论
  
# re: 图片上传压缩处理(可以正常实现bmp转jpg、png转jpg、gif转jpg,但是暂时还没有解决gif转gif的功能)
2012-07-05 15:30 | 小邢
麻烦您把这个改写成javascript格式的好吗?  回复  更多评论
  

只有注册用户登录后才能发表评论。


网站导航: