图片处理工具类

import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.awt.image.ColorModel;
import java.awt.image.WritableRaster;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Iterator;

import javax.imageio.IIOImage;
import javax.imageio.ImageIO;
import javax.imageio.ImageTypeSpecifier;
import javax.imageio.ImageWriteParam;
import javax.imageio.ImageWriter;
import javax.imageio.stream.ImageOutputStream;

import org.apache.commons.lang.StringUtils;

/**
 *
 * File Name : ImageUtil.java
 *
 * @Description : Image 工具类</br>主要用于按指定大小截图
 */
public class ImageUtil
{

    /**
     * Description : <Detail Description for method>
     *
     * @param args
     *
     */
    public static void main(String[] args)
    {
        try
        {
            compressImage(
                    new File("F://20110406//in//201103280004570089c.jpg"),
                    new File("F://20110406//out//201103280004570089c.jpg"),
                    0.5f);
            saveAndCutImage(new File(
                    "F://20110406//in//201103280004570089c.jpg"), new File(
                    "F://20110406//out//201103280004570089c.jpg"), 561, 411,
                    false);
            saveAndCutImage(new File(
                    "F://20110406//in//201103280004570089c.jpg"), new File(
                    "F://20110406//out//201103280004570089c(448_290).jpg"),
                    448, 290, true);
        } catch (Exception e)
        {
            e.printStackTrace();
        }
    }

    /**
     *
     * Description : 按比例缩放图片
     *
     * @param source
     *            要缩放的给定图片源
     * @param targetW
     *            给定宽度
     * @param targetH
     *            给定高度
     * @return
     *
     */
    public static BufferedImage resize(BufferedImage source, int targetW,
            int targetH, boolean proportion)
    {
        int type = source.getType();
        BufferedImage target;
        double sw = (double) targetW / source.getWidth();
        double sh = (double) targetH / source.getHeight();
        // 是否需要按比例缩放,若为false则按照给定的大小,这样会变形
        if (proportion)
        {
            if (sw > sh)
            {
                sh = sw;
                targetH = (int) (sh * source.getHeight());
            } else
            {
                sw = sh;
                targetW = (int) (sw * source.getWidth());
            }
        }

        if (type == BufferedImage.TYPE_CUSTOM)
        {
            ColorModel cm = source.getColorModel();
            WritableRaster raster = cm.createCompatibleWritableRaster(targetW,
                    targetH);
            boolean alphaPremultiplied = cm.isAlphaPremultiplied();
            target = new BufferedImage(cm, raster, alphaPremultiplied, null);
        } else
        {
            target = new BufferedImage(targetW, targetH, type);
        }
        Graphics2D g = target.createGraphics();
        g.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
                RenderingHints.VALUE_INTERPOLATION_BICUBIC);
        g.drawRenderedImage(source, AffineTransform.getScaleInstance(sw, sh));
        g.dispose();
        return target;
    }

    /**
     *
     * Description : 按给定大小保存截图
     *
     * @param inFilePath
     *            图片源
     * @param outFilePath
     *            输出文件
     * @param width
     *            宽度
     * @param hight
     *            高度
     * @param proportion
     *            是否需要等比例缩放
     * @throws Exception
     *
     */
    public static void saveAndCutImage(File inFile, File outFile, int width,
            int hight, boolean proportion) throws Exception
    {
        saveAndCutImage(inFile, outFile, width, hight, proportion, 1f);
    }

    /**
     *
     * Description : 按给定大小保存截图
     *
     * @param inFilePath
     *            图片源
     * @param outFilePath
     *            输出文件
     * @param width
     *            宽度
     * @param hight
     *            高度
     * @param proportion
     *            是否需要等比例缩放
     * @param quality
     *            压缩质量
     * @throws Exception
     *
     */
    public static void saveAndCutImage(File inFile, File outFile, int width,
            int hight, boolean proportion, float quality) throws Exception
    {
        InputStream in = new FileInputStream(inFile);
        File saveFile = outFile;

        BufferedImage srcImage = ImageIO.read(in);
        if (width > 0 || hight > 0)
        {
            // 原图的大小
            int sw = srcImage.getWidth();
            int sh = srcImage.getHeight();
            // 如果原图像的大小小于要缩放的图像大小,直接将要缩放的图像复制过去
            if (sw > width && sh > hight)
            {
                srcImage = resize(srcImage, width, hight, proportion);
            } else
            {
                compressImage(srcImage, saveFile, quality);
                if (saveFile.length() > inFile.length())
                {
                    String fileName = saveFile.getName();
                    String formatName = "";
                    int pos = fileName.lastIndexOf('.');
                    if (pos > -1)
                    {
                        formatName = fileName.substring(pos + 1).toLowerCase();
                    }
                    ImageIO.write(srcImage, formatName, outFile);
                }
                return;
            }
        }
        // 缩放后的图像的宽和高
        int w = srcImage.getWidth();
        int h = srcImage.getHeight();
        // 如果缩放后的图像和要求的图像宽度一样,就对缩放的图像的高度进行截取
        if (w == width)
        {
            // 计算X轴坐标
            int x = 0;
            int y = h / 2 - hight / 2;
            saveSubImage(srcImage, new Rectangle(x, y, width, hight), saveFile,
                    quality);
        }
        // 否则如果是缩放后的图像的高度和要求的图像高度一样,就对缩放后的图像的宽度进行截取
        else if (h == hight)
        {
            // 计算X轴坐标
            int x = w / 2 - width / 2;
            int y = 0;
            saveSubImage(srcImage, new Rectangle(x, y, width, hight), saveFile,
                    quality);
        }
        in.close();
    }

    /**
     *
     * Description : 截图
     *
     * @param image
     *            需要截图的图片源
     * @param subImageBounds
     *            子图范围
     * @param subImageFile
     *            子图文件
     * @param quality
     *            压缩质量
     * @throws IOException
     *
     */
    private static void saveSubImage(BufferedImage image,
            Rectangle subImageBounds, File subImageFile, float quality)
            throws IOException
    {
        if (subImageBounds.x < 0 || subImageBounds.y < 0
                || subImageBounds.width - subImageBounds.x > image.getWidth()
                || subImageBounds.height - subImageBounds.y > image.getHeight())
        {
            System.out.println("Bad   subimage   bounds");
            return;
        }
        BufferedImage subImage = image.getSubimage(subImageBounds.x,
                subImageBounds.y, subImageBounds.width, subImageBounds.height);
        compressImage(subImage, subImageFile, quality);
    }

    /**
     *
     * Description : 压缩图片 只对输出为jpeg类型的图片进行压缩,其它输出类型图片不进行压缩处理
     *
     * @param inFile
     *            输入图片文件
     * @param outFile
     *            输出图片文件
     * @param quality
     *            压缩质量
     * @throws IOException
     *
     */
    public static void compressImage(File inFile, File outFile, float quality)
            throws Exception
    {
        boolean needCompressFlag = true;
        String inFileName = inFile.getName();
        String inFormatName = "";
        int pos = inFileName.lastIndexOf('.');
        if (pos > -1)
        {
            inFormatName = inFileName.substring(pos + 1).toLowerCase();
        }
        if (StringUtils.isBlank(inFormatName))
        {
            throw new IllegalArgumentException("输入图片文件必须要有后缀名!");
        }
        String outFileName = outFile.getName();
        String outFormatName = "";
        pos = outFileName.lastIndexOf('.');
        if (pos > -1)
        {
            outFormatName = outFileName.substring(pos + 1).toLowerCase();
        }
        if (StringUtils.isBlank(outFormatName))
        {
            throw new IllegalArgumentException("输出图片文件必须要有后缀名!");
        }
        boolean jpgFlag = "jpg".equals(outFormatName)
                || "jpeg".equals(outFormatName);
        // 相同文件类型,但输出不是jpg,直接图片复制
        if (outFormatName.equals(inFormatName) && !jpgFlag)
        {
            FileUtil.copy(inFile, outFile);
            return;
        }

        InputStream in = new FileInputStream(inFile);
        BufferedImage inImage = ImageIO.read(in);
        if (jpgFlag)
        {
            int sw = inImage.getWidth();
            int sh = inImage.getHeight();
            long inSize = inFile.length();
            needCompressFlag = ((sw * sh * 0.21) < inSize);
            if (needCompressFlag)
            {
                compressImage(inImage, outFile, quality);
                if (outFile.length() > inSize)
                {
                    needCompressFlag = false;
                }
            }
        }
        if (!needCompressFlag)
        {
            ImageIO.write(inImage, outFormatName, outFile);
        }
        in.close();
    }

    /**
     *
     * Description : 压缩图片 只对输出为jpeg类型的图片进行压缩,其它输出类型图片不进行压缩处理
     *
     * @param image
     *            图片源
     * @param imageFile
     *            输出图片文件
     * @param quality
     *            压缩质量
     * @throws IOException
     *
     */
    private static void compressImage(BufferedImage image, File imageFile,
            float quality) throws IOException
    {
        String fileName = imageFile.getName();
        String formatName = "";
        int pos = fileName.lastIndexOf('.');
        if (pos > -1)
        {
            formatName = fileName.substring(pos + 1).toLowerCase();
        }
        if (StringUtils.isBlank(formatName))
        {
            throw new IllegalArgumentException("输出图片文件必须要有后缀名!");
        }
        boolean jpg = ("jpg".equals(formatName) || "jpeg".equals(formatName));
        boolean needCompressFlag = 1.0f > quality;
        if (needCompressFlag && jpg)
        {
            ImageWriter writer = null;
            ImageTypeSpecifier type = ImageTypeSpecifier
                    .createFromRenderedImage(image);
            Iterator<ImageWriter> iter = ImageIO.getImageWriters(type, "jpg");
            if (iter.hasNext())
            {
                writer = (ImageWriter) iter.next();
            }
            if (writer == null)
            {
                ImageIO.write(image, formatName, imageFile);
                return;
            }
            IIOImage iioImage = new IIOImage(image, null, null);
            ImageWriteParam param = writer.getDefaultWriteParam();
            param.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
            param.setCompressionQuality(quality);
            ImageOutputStream outputStream = ImageIO
                    .createImageOutputStream(imageFile);
            writer.setOutput(outputStream);
            writer.write(null, iioImage, param);
            writer.dispose();
            outputStream.flush();
            outputStream.close();
            return;
        }
        ImageIO.write(image, formatName, imageFile);
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值