象qq相册那样,上传的相片要另外再生成一张小张的缩略图,试了几种方式都不理想。
不知道哪位大侠有做过这种东西,要象qq相册那样的压缩效果。

解决方案 »

  1.   


    http://blog.csdn.net/fancyerII/archive/2010/08/25/5837991.aspx
      

  2.   

    必须使用插值算法的。以下使用Lanczos算法:package chdw.image;import java.awt.image.BufferedImage;
    import java.io.File;import javax.imageio.ImageIO;public class Lanczos {
    private static final double WORK_LOAD_FACTOR = 0.265; private static final double LANCZOS_SUPPORT = 3;
    private static final double LANCZOS_WINDOW = 3;
    private static final double LANCZOS_SCALE = 1;
    private static final double LANCZOS_BLUR = 1; private static final double EPSILON = 1.0e-6; private static class ContributionInfo {
    private double weight;
    private int pixel;
    }

    public static BufferedImage resizeImage(BufferedImage image, double ratio) {
    return resizeImage(image, (int)(image.getWidth() * ratio + 0.5), (int)(image.getHeight() * ratio + 0.5));
    } public static BufferedImage resizeImage(BufferedImage image, double xRatio, double yRatio) {
    return resizeImage(image, (int)(image.getWidth() * xRatio + 0.5), (int)(image.getHeight() * yRatio + 0.5));
    }

    public static BufferedImage resizeImage(BufferedImage image, int width, int height) {
    double xFactor = width * 1.0 / image.getWidth();
    double yFactor = height * 1.0 / image.getHeight(); BufferedImage resizeImage = new BufferedImage(width, height, image.getType());
    BufferedImage filterImage = null; if (xFactor * yFactor > WORK_LOAD_FACTOR) {
    filterImage = new BufferedImage(width, image.getHeight(), image.getType());
    horizontalFilter(image, filterImage, xFactor);
    verticalFilter(filterImage, resizeImage, yFactor);
    } else {
    filterImage = new BufferedImage(image.getWidth(), height, image.getType());
    verticalFilter(image, filterImage, yFactor);
    horizontalFilter(filterImage, resizeImage, xFactor);
    }
    return resizeImage;
    } private static void verticalFilter(BufferedImage image, BufferedImage resizeImage,
    double yFactor) {
    double scale = Math.max(1.0 / yFactor, 1.0);
    double support = scale * LANCZOS_SUPPORT;
    if (support < 0.5) {
    support = 0.5;
    scale = 1.0;
    }
    scale = 1.0 / scale; for (int y = 0; y < resizeImage.getHeight(); y++) {
    double center = (y + 0.5) / yFactor;
    int start = (int) (Math.max(center - support - EPSILON, 0.0) + 0.5);
    int stop = (int) (Math.min(center + support, image.getHeight()) + 0.5);
    double density = 0.0;
    ContributionInfo[] contribution = new ContributionInfo[stop - start];
    int n;
    for (n = 0; n < (stop - start); n++) {
    contribution[n] = new ContributionInfo();
    contribution[n].pixel = start + n;
    contribution[n].weight = getResizeFilterWeight(scale * (start + n - center + 0.5));
    density += contribution[n].weight;
    } if ((density != 0.0) && (density != 1.0)) {
    density = 1.0 / density;
    for (int i = 0; i < n; i++)
    contribution[i].weight *= density;
    }
    for (int x = 0; x < resizeImage.getWidth(); x++) {
    double red = 0;
    double green = 0;
    double blue = 0;
    for (int i = 0; i < n; i++) {
    double alpha = contribution[i].weight;
    int rgb = image.getRGB(x, contribution[i].pixel);
    red += alpha * ((rgb >> 16) & 0xFF);
    green += alpha * ((rgb >> 8) & 0xFF);
    blue += alpha * (rgb & 0xFF);
    }
    int rgb = roundToQuantum(red) << 16 | roundToQuantum(green) << 8
    | roundToQuantum(blue);
    resizeImage.setRGB(x, y, rgb);
    }
    }
    } private static void horizontalFilter(BufferedImage image, BufferedImage resizeImage,
    double xFactor) {
    double scale = Math.max(1.0 / xFactor, 1.0);
    double support = scale * LANCZOS_SUPPORT;
    if (support < 0.5) {
    support = 0.5;
    scale = 1.0;
    }
    scale = 1.0 / scale; for (int x = 0; x < resizeImage.getWidth(); x++) {
    double center = (x + 0.5) / xFactor;
    int start = (int) (Math.max(center - support - EPSILON, 0.0) + 0.5);
    int stop = (int) (Math.min(center + support, image.getWidth()) + 0.5);
    double density = 0.0;
    ContributionInfo[] contribution = new ContributionInfo[stop - start];
    int n;
    for (n = 0; n < (stop - start); n++) {
    contribution[n] = new ContributionInfo();
    contribution[n].pixel = start + n;
    contribution[n].weight = getResizeFilterWeight(scale * (start + n - center + 0.5));
    density += contribution[n].weight;
    } if ((density != 0.0) && (density != 1.0)) {
    density = 1.0 / density;
    for (int i = 0; i < n; i++)
    contribution[i].weight *= density;
    }
    for (int y = 0; y < resizeImage.getHeight(); y++) {
    double red = 0;
    double green = 0;
    double blue = 0;
    for (int i = 0; i < n; i++) {
    double alpha = contribution[i].weight;
    int rgb = image.getRGB(contribution[i].pixel, y);
    red += alpha * ((rgb >> 16) & 0xFF);
    green += alpha * ((rgb >> 8) & 0xFF);
    blue += alpha * (rgb & 0xFF);
    }
    int rgb = roundToQuantum(red) << 16 | roundToQuantum(green) << 8
    | roundToQuantum(blue);
    resizeImage.setRGB(x, y, rgb);
    }
    }
    } private static double getResizeFilterWeight(double x) {
    double blur = Math.abs(x) / LANCZOS_BLUR;
    double scale = LANCZOS_SCALE / LANCZOS_WINDOW;
    scale = sinc(blur * scale);
    return scale * sinc(blur);
    } private static double sinc(double x) {
    if (x == 0.0)
    return 1.0;
    return Math.sin(Math.PI * x) / (Math.PI * x);
    } private static int roundToQuantum(double value) {
    if (value <= 0.0)
    return 0;
    if (value >= 255)
    return 255;
    return (int) (value + 0.5);
    }

    public static void main(String[] args) throws Exception {
    BufferedImage image = ImageIO.read(new File("d:/src.png"));
    ImageIO.write(resizeImage(image, 400, 300), "PNG", new File("d:/dest.png"));
    }
    }
      

  3.   

    package com.ibmssz.test;import java.awt.Image;  
    import java.awt.image.BufferedImage;
    import java.io.File;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.OutputStream;import javax.imageio.ImageIO;import com.sun.image.codec.jpeg.JPEGCodec;
    import com.sun.image.codec.jpeg.JPEGImageEncoder;public class lessenImg { public static void main(String[] args) {
    File file=new File("D://1.jpg");//原图片
    try {
    Image src=ImageIO.read(file);
    BufferedImage bufferedImage=new BufferedImage(240,200,BufferedImage.TYPE_INT_RGB);//设置图片大小
    bufferedImage.getGraphics().drawImage(src,0,0,240,200,null);//绘制图片大小,两个一致...
    OutputStream os=new FileOutputStream("D://aa.jpg");//生成图片
    JPEGImageEncoder encoder=JPEGCodec.createJPEGEncoder(os);
    encoder.encode(bufferedImage);
    os.close();
    System.out.println("完成");
    } catch (IOException e) {
    e.printStackTrace();
    }
    }
    }
      

  4.   

    充分利用Graphics2D就OK了,下面的代码以测试过,没问题,使用于PNG图片   /**
         * 图片等比压缩
         * @param destImage 要压缩的图片
         * @param width 指定宽度
         * @param height 指定高度
         * @return 压缩后的图片
         * @throws IOException 图片操作异常
         */
        public static BufferedImage getThumbnail(BufferedImage destImage,int width,int height) throws IOException{
            if(destImage==null) throw new NullPointerException("destImage is null");
            Graphics2D g2D=null;
            BufferedImage image=null;
            int wid=destImage.getWidth();
            int hig=destImage.getHeight();
            image= new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
            g2D = (Graphics2D) image.getGraphics();
            if(wid<=width && hig<=height){
            }else if(wid <=width && hig>height){
                wid=(wid*height)/hig;
                hig=height;
            }else if(wid>width && hig<=height){
                wid=width;
                hig=(hig*width)/wid;
            }else if(wid>width && hig>height){
               if(wid>=hig){
                   wid=width;
                   hig=(hig*width)/hig;
               }else{
                   wid=(wid*height)/hig;
                   hig=height;
               }
            }
            g2D.drawImage(destImage, 0, 0, wid, hig, null);
            ImageIO.write(image, "png", new File("cut/resize.png"));
            return image;
        }
      

  5.   

    java-image-scaling -- Hight quality image scaling library
    http://code.google.com/p/java-image-scaling/