`

图像压缩实用类

    博客分类:
  • J2SE
阅读更多
转载:http://hi.baidu.com/javajavajava/blog
import java.awt.Color;
import java.awt.Component;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.MediaTracker;
import java.awt.Toolkit;
import java.awt.image.BufferedImage;
import java.awt.image.ConvolveOp;
import java.awt.image.Kernel;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;

import javax.imageio.ImageIO;
import javax.swing.ImageIcon;

import com.sun.image.codec.jpeg.JPEGCodec;
import com.sun.image.codec.jpeg.JPEGEncodeParam;
import com.sun.image.codec.jpeg.JPEGImageEncoder;

/**
* 图像压缩工具
* @author lihuoming@sohu.com
*
*/
public class ImageSizer {
    public static final MediaTracker tracker = new MediaTracker(new Component() {
        private static final long serialVersionUID = 1234162663955668507L;}
    );
    /**
     * @param originalFile 原图像
     * @param resizedFile 压缩后的图像
     * @param width 图像宽
     * @param format 图片格式 jpg, png, gif(非动画)
     * @throws IOException
     */
    public static void resize(File originalFile, File resizedFile, int width, String format) throws IOException {
        if(format!=null && "gif".equals(format.toLowerCase())){
            resize(originalFile, resizedFile, width, 1);
            return;
        }
        FileInputStream fis = new FileInputStream(originalFile);
        ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
        int readLength = -1;
        int bufferSize = 1024;
        byte bytes[] = new byte[bufferSize];
        while ((readLength = fis.read(bytes, 0, bufferSize)) != -1) {
            byteStream.write(bytes, 0, readLength);
        }
        byte[] in = byteStream.toByteArray();
        fis.close();
        byteStream.close();

        Image inputImage = Toolkit.getDefaultToolkit().createImage( in );
        waitForImage( inputImage );
        int imageWidth = inputImage.getWidth( null );
        if ( imageWidth < 1 )
           throw new IllegalArgumentException( "image width " + imageWidth + " is out of range" );
        int imageHeight = inputImage.getHeight( null );
        if ( imageHeight < 1 )
           throw new IllegalArgumentException( "image height " + imageHeight + " is out of range" );

        // Create output image.
        int height = -1;
        double scaleW = (double) imageWidth / (double) width;
        double scaleY = (double) imageHeight / (double) height;
        if (scaleW >= 0 && scaleY >=0) {
            if (scaleW > scaleY) {
                height = -1;
            } else {
                width = -1;
            }
        }
        Image outputImage = inputImage.getScaledInstance( width, height, java.awt.Image.SCALE_DEFAULT);
        checkImage( outputImage );
        encode(new FileOutputStream(resizedFile), outputImage, format);
    }

    /** Checks the given image for valid width and height. */
    private static void checkImage( Image image ) {
       waitForImage( image );
       int imageWidth = image.getWidth( null );
       if ( imageWidth < 1 )
          throw new IllegalArgumentException( "image width " + imageWidth + " is out of range" );
       int imageHeight = image.getHeight( null );
       if ( imageHeight < 1 )
          throw new IllegalArgumentException( "image height " + imageHeight + " is out of range" );
    }

    /** Waits for given image to load. Use before querying image height/width/colors. */
    private static void waitForImage( Image image ) {
       try {
          tracker.addImage( image, 0 );
          tracker.waitForID( 0 );
          tracker.removeImage(image, 0);
       } catch( InterruptedException e ) { e.printStackTrace(); }
    }

    /** Encodes the given image at the given quality to the output stream. */
    private static void encode( OutputStream outputStream, Image outputImage, String format )
       throws java.io.IOException {
       int outputWidth = outputImage.getWidth( null );
       if ( outputWidth < 1 )
          throw new IllegalArgumentException( "output image width " + outputWidth + " is out of range" );
       int outputHeight = outputImage.getHeight( null );
       if ( outputHeight < 1 )
          throw new IllegalArgumentException( "output image height " + outputHeight + " is out of range" );

       // Get a buffered image from the image.
       BufferedImage bi = new BufferedImage( outputWidth, outputHeight,
          BufferedImage.TYPE_INT_RGB );
       Graphics2D biContext = bi.createGraphics();
       biContext.drawImage( outputImage, 0, 0, null );
       ImageIO.write(bi, format, outputStream);
       outputStream.flush();
    }

    /**
    * 缩放gif图片
    * @param originalFile 原图片
    * @param resizedFile 缩放后的图片
    * @param newWidth 宽度
    * @param quality 缩放比例 (等比例)
    * @throws IOException
    */
    private static void resize(File originalFile, File resizedFile, int newWidth, float quality) throws IOException {
        if (quality < 0 || quality > 1) {
            throw new IllegalArgumentException("Quality has to be between 0 and 1");
        }
        ImageIcon ii = new ImageIcon(originalFile.getCanonicalPath());
        Image i = ii.getImage();
        Image resizedImage = null;
        int iWidth = i.getWidth(null);
        int iHeight = i.getHeight(null);
        if (iWidth > iHeight) {
            resizedImage = i.getScaledInstance(newWidth, (newWidth * iHeight) / iWidth, Image.SCALE_SMOOTH);
        } else {
            resizedImage = i.getScaledInstance((newWidth * iWidth) / iHeight, newWidth, Image.SCALE_SMOOTH);
        }
        // This code ensures that all the pixels in the image are loaded.
        Image temp = new ImageIcon(resizedImage).getImage();
        // Create the buffered image.
        BufferedImage bufferedImage = new BufferedImage(temp.getWidth(null), temp.getHeight(null),
                                                        BufferedImage.TYPE_INT_RGB);
        // Copy image to buffered image.
        Graphics g = bufferedImage.createGraphics();
        // Clear background and paint the image.
        g.setColor(Color.white);
        g.fillRect(0, 0, temp.getWidth(null), temp.getHeight(null));
        g.drawImage(temp, 0, 0, null);
        g.dispose();
        // Soften.
        float softenFactor = 0.05f;
        float[] softenArray = {0, softenFactor, 0, softenFactor, 1-(softenFactor*4), softenFactor, 0, softenFactor, 0};
        Kernel kernel = new Kernel(3, 3, softenArray);
        ConvolveOp cOp = new ConvolveOp(kernel, ConvolveOp.EDGE_NO_OP, null);
        bufferedImage = cOp.filter(bufferedImage, null);
        // Write the jpeg to a file.
        FileOutputStream out = new FileOutputStream(resizedFile);
        // Encodes image as a JPEG data stream
        JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);
        JPEGEncodeParam param = encoder.getDefaultJPEGEncodeParam(bufferedImage);
        param.setQuality(quality, true);
        encoder.setJPEGEncodeParam(param);
        encoder.encode(bufferedImage);
    }
}

分享到:
评论

相关推荐

    分形图像压缩综述

    分形图像编码算法主要分为两大类:分形模型图像压缩编码和IFS分形图像压缩编码。分形模型图像压缩编码通过事先建立分形模型来编码,而IFS分形图像压缩编码则是利用迭代方法得到原始图像的近似。其中,IFS方法由于其...

    基于图像块之间信息冗余的数字图像压缩新技术.pdf

    ### 基于图像块之间信息冗余的数字图像压缩新技术 #### 摘要解析与核心知识点 本文介绍了一种新型的数字图像压缩技术,该技术特别适用于存储空间受到严格限制的情况。主要通过分析图像块之间的信息冗余来实现高效...

    数字图像处理,压缩与识别技术

    然后,我们转向图像压缩。图像数据通常非常庞大,压缩技术能有效减少存储空间和传输时间。常见的压缩方法有无损压缩和有损压缩。无损压缩如Huffman编码和LZW编码,能够完全恢复原始数据,但压缩率相对较低。有损压缩...

    图像压缩软件

    在IT行业中,图像压缩软件是至关重要的工具,尤其是在多媒体处理和数据存储方面。本文将深入探讨使用C#语言开发图像...开发者需要掌握图像压缩算法、C#编程和GUI设计等多方面的知识,才能打造出一款实用且高效的软件。

    基于APIDCT和自适应霍夫曼编码的静态图像压缩算法.doc

    图像压缩算法可以分为两大类:无损压缩和有损压缩。无损压缩是指通过去除冗余信息来实现图像压缩的方法,而有损压缩是指通过去除部分图像信息来实现图像压缩的方法。常用的图像压缩算法包括 JPEG、GIF、PNG 等。 在...

    实用图像处理类

    本主题将深入探讨一个专门处理RLE8压缩BMP图像的实用图像处理类,该类是用C++编程语言实现的。 首先,让我们了解什么是RLE8(Run-Length Encoding 8)压缩。这是一种简单的无损数据压缩算法,常用于存储256色位图...

    实验四图像压缩编码概要.pdf

    图像压缩编码是数字图像处理领域的一项核心技术,目的在于减少图像数据的存储容量以及提高网络传输的效率,同时尽可能地保持图像的视觉质量。图像压缩编码技术的分类有两大主流:无损压缩和有损压缩。无损压缩确保...

    数字图像处理与通信:图像压缩(二).pdf

    《数字图像处理与通信:图像压缩(二)》一文中主要探讨了图像压缩技术,特别是有损压缩的方法和原理。图像压缩是数字图像处理的重要环节,它旨在减少图像数据量,便于存储和传输。 首先,文章提到了图像压缩的基本...

    matlab-基于DCT变换的图像压缩解压缩算法matlab仿真-源码

    总之,基于DCT的图像压缩解压缩算法在MATLAB中的实现是一个实用的示例,它涵盖了图像处理中的关键概念,如DCT变换、量化和IDCT。通过实际操作这些代码,学习者可以更好地掌握图像压缩的原理,并了解如何在MATLAB环境...

    JPEG.rar_JPEG图像压缩_jpeg 压缩率_site:www.pudn.com

    总结来说,JPEG是一种实用的静态图像压缩标准,利用DCT和量化实现高效的数据压缩,同时允许用户根据需要调整压缩率。尽管存在一定的质量损失,但其广泛支持和灵活的压缩选项使其成为数字图像处理领域不可或缺的一...

    分形图像压缩的一些详细资料

    例如,通过并行计算技术和机器学习算法的结合,可以显著提高编码效率,使得分形压缩成为一种更加实用的图像压缩技术。同时,针对特定类型图像的优化算法也在不断发展中,为分形压缩技术开辟了新的应用场景。

    C语言实用数字图像处理

    - 图像压缩技术对于实现高质量的视频通话至关重要。 - **可逆编码与非可逆编码**: - 可逆编码(无损压缩)保留所有原始数据,而非可逆编码(有损压缩)会丢失部分数据。 - **二值图像的编码法(游程长度编码法)**: ...

    一种新的图像压缩编码算法研究

    基于小波变换的图像压缩算法主要分为两大类:一类是基于零树或零块结构的编码方法,如EZW、SPIHT(Set Partitioning in Hierarchical Trees)、SPECK(Spatial Embedding with Partitioning of the Coefficient ...

    批量照片压缩图片压缩实用工具

    "批量照片压缩图片压缩实用工具"是一款专为此目的设计的软件,它能够有效地减小图片文件的大小,同时尽可能保持图片的质量。这款工具对于那些需要管理大量照片,如摄影师、设计师或者普通用户来说,是一个非常实用的...

    图像视频压缩教程,绝对超值

    静止图像压缩标准是JPEG(Joint Photographic Experts Group)是最广泛使用的标准之一。JPEG提供高压缩比,同时保持良好的图像质量。其优点在于可选择有损或无损压缩,用户可以根据需求调整压缩级别和图像质量。JPEG...

    图片压缩工具类

    "图片压缩工具类"的标题暗示了这是一个专门用于处理图像压缩的软件或代码库,旨在提供多样的图片压缩方法,追求快速高效的同时,还能保证图片的质量。描述中提到“无损”压缩,意味着该工具在压缩图片时不会降低原始...

    《Matlab计算机视觉与深度学习实战》代码 基于霍夫曼图像压缩重建.zip

    书中涵盖了许多实用的技术和算法,而提供的"基于霍夫曼图像压缩重建"的代码则聚焦于图像处理中的一个重要领域:数据压缩。霍夫曼编码是一种无损数据压缩方法,它通过构建最优前缀树来实现对频繁出现的数据符号进行更...

    基于数据挖掘的图像压缩域肤色检测算法.pdf

    基于数据挖掘的图像压缩域肤色检测算法是图像处理领域中的一项技术,涉及肤色检测、图像压缩、数据挖掘和区域生长等多个知识点。肤色检测作为图像处理的关键技术之一,主要用于人脸检测与识别、手势识别、敏感图像...

Global site tag (gtag.js) - Google Analytics