`

图像压缩实用类

    博客分类:
  • 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);
    }
}

分享到:
评论

相关推荐

    神经网络图像压缩算法的FPGA实现技术研究

    神经网络图像压缩是图像压缩和神经网络领域的主要研究方向之一,基于多层前馈神经网络的压缩算法在神经网络压缩算法中最有代表性。本文结合国家某科研项目对该类算法的硬件实现进行研究,具有重要的理论和实用价值。...

    实用图像处理类

    一个实用的图像处理类,只处理RLE8压缩BMP图,即256色位图。

    C#数字图像处理算法典型实例.iso

    C#数字图像处理算法典型实例共11章,分别讲述了图像的点运算、几何运算、数学形态学图像处理方法、频率变换、图像平滑与去噪、边缘检测、图像分割、图像压缩编码和彩色图像处理等相关技术。本书的光盘中附有相关章节...

    基于DSP的图像压缩无线传输系统设计

    该系统设计适用于低端低价位无线图像传输产品或消费电子类产品,特别适合于家庭和临时场所使用的低端无线监控系统。  1 引言  随着航空航天技术的发展,图像无线传输技术日趋成熟。而嵌入式图像无线传输技术以其...

    视觉注意模型及其在图像处理中的应用

    对视觉注意机制进行计算机模拟一直是计算神经科学领域中一个富有挑战力的工作,同 ...分类、助航系统、机器人控制、目标跟踪、图像分割、图像压缩、视频编码、图像质量评价、 图片编辑、图像检索等。

    单片机与DSP中的基于DSP的图像压缩无线传输系统设计

    该系统设计适用于低端低价位无线图像传输产品或消费电子类产品,特别适合于家庭和临时场所使用的低端无线监控系统。  1 引言  随着航空航天技术的发展,图像无线传输技术日趋成熟。而嵌入式图像无线传输技术以其...

    《数字图像处理》冈萨雷斯 第三版part1(共1-3部分)

    第8章 图像压缩  前言  8.1 背景知识  8.2 编码冗余  8.2.1 霍夫曼码  8.2.2 霍夫曼编码  8.2.3 霍夫曼解码  8.3 像素间的冗余  8.4 心理视觉冗余  8.5 JPEG压缩  8.5.1 JPEG  8.5.2 JPEG 2000  小结 第...

    文档解压缩工具 WinZip 20.0 中文免费版.zip

    除此之外,还能将文件直接压缩发送给QQ好友、生成自解压式EXE文件、解压后直接打开文件等多种实用的功能。当然 Winrar 也是一款经典小巧的解压缩工具,本站也有中文非商业个人版。 我们在网上下载文件时或是日常...

    基于改进正交匹配追踪算法的压缩感知雷达成像方法

    首先建立了步进频雷达回波的稀疏表示模型,根据稀疏字典和压缩测量的2维可分离特性,提出一种改进的OMP算法用于雷达图像形成,大大提高了计算效率,并很容易扩展到其他贪婪类算法中。从理论上对几种CS成像算法的性能...

    vc++数字图象获取,处理及实践应用源代码

    全书由自成体系而又互有联系的12章组成,分别讨论了位图及图像类的概念、图像获取、图像增强、正交变换、压缩编码、图像配准、运动检测、特征提取、图像分割及识别的相关知训,基本涵概了从图像获取到图像处理的各个...

    Java2实用教程.rar

    4 20 2将类压缩成JAR文件 4 20 3更新 查看JAR文件 习题 第5章字符串 5 1字符串 5 2字符串的常用方法 5 3字符串与基本数据的相互转化 5 4对象的字符串表示 5 5StringTokenizer类 5 6字符串与字符 字节数组 5 7...

    ImageOptim 1.8.8 Mac无损图片压缩小工具汉化版 设计师最爱

    ImageOptim 支持 PNG/JPEG/GIF 动画,本质是各种影像优化...这可是APP切图最实用的无损图片压缩神器。 另外,如果各位想要对APP切图@2x,@3x图片资源进行批量压缩的话,方法非常简单!全选拖到下面这个压缩界面就行啦!

    基于稀疏表示的电力设备图像识别方法

    电力设备图像分析对于电力巡线、检修具有重要的实用意义。本文提出一种基于稀疏表示的电力设备图像识别方法。考虑到图像采集过程中不可避免受到光线条件、噪声干扰等因素的影响,本方法采用贝叶斯压缩感知算法求解...

    论文研究-三角域上.pdf

    目前的数字图像水印对于加噪、滤波、JPEG压缩攻击具有很好的鲁棒性但抗几何类攻击仍是对数字图像水印的一个巨大挑战。将水印嵌入到图像中的不变域中,这是一种比较好的方法。然而,由于嵌入水印的原始图像和受到几何...

    Java2实用教程(第三版)

    全书共分17章,分别介绍了Java的基本数据类型、语句、类、对象、接口、内部类、异常处理、字符串、实用类、AWT组件、多线程、输入输出流、网络编程、Java Applet、数据结构类、JDBC、Java Swing等内容。 本书不仅...

    神奇图像转换处理软件 v2.0.0.264官方版

    基本简介 神奇图像转换处理软件是图像处理类软件,内置格式转换、图片加水印、图片批处理、批量缩放图片、批量压缩JPG、看图重命名、图片分割、大图打印等多种功能。简单的设计,实用的功能!只需一个软件,即可...

    Java2实用教程(第三版).part1.rar

    全书共分17章,分别介绍了Java的基本数据类型、语句、类、对象、接口、内部类、异常处理、字符串、实用类、AWT组件、多线程、输入输出流、网络编程、Java Applet、数据结构类、JDBC、Java Swing等内容。 本书不仅...

    洋芋田图像工具箱3.5一个专为摄影师设计的图像工具箱.rar

     支持一级标题、二级标题、文本、粗体、斜体、、有序列表、无序列表、图片和段落引用,支持自定义每一类富文本内容的字体、字体大小、字体颜色、行距、外边距、对齐方式等各项内容,也支持全文背景和页面边距的...

    C#公共类通用类非常齐全

    这个类提供了实用方法的字节数组和图像之间的转换。(ByteImageConvertor.cs) byte字节数组操作辅助类(BytesTools.cs) 处理数据类型转换,数制转换、编码转换相关的类(ConvertHelper.cs) CRC校验辅助类(CRCUtils....

Global site tag (gtag.js) - Google Analytics