图片处理工具类ImageHelper

相信大家在平时项目开发中,多少都会遇到跟图片图片,比如根据文件内容生成图片,修改图片的像素大小,png转换jpg类型转换,给图片添加背景图片,或者添加水印等等。 我之前在做项目中的时候,就遇到这样的业务需求,针对此类的操作,我把它封装在ImageHelper工具类中,源码如下所示,大家可以根据自己的需求进行优化。

package tools.util;

import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
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.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.math.BigDecimal;
import java.math.MathContext;
import java.util.ArrayList;

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

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

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

/***
 * 对图片进行操作  *
 *
 * @author youqiang.xiong
 * @since 2016.11.16
 * */
public class ImageHelper {

    protected static Logger log = LoggerFactory.getLogger(ImageHelper.class);

    private static ImageHelper imageHelper = null;

    public static ImageHelper getImageHelper() {
        if (imageHelper == null) {
            imageHelper = new ImageHelper();
        }
        return imageHelper;
    }

    /***
     * * 按指定的比例缩放图片
     * 
     * @param sourceImagePath
     *            源地址
     * @param destinationPath
     *            改变大小后图片的地址
     * @param scale
     *            缩放比例,如1.2
     * @throws Exception
     * @throws IOException
     */
    public static void scaleImage(String sourceImagePath,
            String destinationPath, double scale, String format)
            throws Exception {
        log.info("图片原路径:" + sourceImagePath + "\t 图片目录路径:" + destinationPath);
        File file = new File(sourceImagePath);
        BufferedImage bufferedImage;

        try {
            bufferedImage = ImageIO.read(file);
            int width = bufferedImage.getWidth();
            int height = bufferedImage.getHeight();
            width = parseDoubleToInt(width * scale);
            height = parseDoubleToInt(height * scale);
            Image image = bufferedImage.getScaledInstance(width, height,
                    Image.SCALE_SMOOTH);
            BufferedImage outputImage = new BufferedImage(width, height,
                    BufferedImage.TYPE_INT_RGB);
            Graphics graphics = outputImage.getGraphics();
            graphics.drawImage(image, 0, 0, null);
            graphics.dispose();
            ImageIO.write(outputImage, format, new File(destinationPath));
        } catch (IOException e) {
            log.error("{}", e);
            throw new Exception("放入目标路径报错,Temp目录未生成。" + e.getMessage());
        }

    }

    /***
     * * 将图片缩放到指定的高度或者宽度 *
     * 
     * @param sourceImagePath
     *            图片源地址
     * @param destinationPath
     *            压缩完图片的地址
     * @param width
     *            缩放后的宽度
     * @param height
     *            缩放后的高度
     * @param auto
     *            是否自动保持图片的原高宽比例
     * @param format
     *            图片格式 例如 jpg
     */
    public static void scaleImageWithParams(String sourceImagePath,
            String destinationPath, int width, int height, boolean auto,
            String format) {
        try {
            File file = new File(sourceImagePath);
            BufferedImage bufferedImage = null;
            bufferedImage = ImageIO.read(file);
            if (auto) {
                ArrayList<Integer> paramsArrayList = getAutoWidthAndHeight(
                        bufferedImage, width, height);
                width = paramsArrayList.get(0);
                height = paramsArrayList.get(1);
                log.info("自动调整比例,width=" + width + " height=" + height);
            }
            Image image = bufferedImage.getScaledInstance(width, height,
                    Image.SCALE_DEFAULT);
            BufferedImage outputImage = new BufferedImage(width, height,
                    BufferedImage.TYPE_INT_RGB);
            Graphics graphics = outputImage.getGraphics();
            graphics.drawImage(image, 0, 0, null);
            graphics.dispose();
            ImageIO.write(outputImage, format, new File(destinationPath));
        } catch (Exception e) {
            log.info("scaleImageWithParams方法压缩图片时出错了");
            log.error("{}", e);
        }
    }

    /***
     * * 将图片缩放到大小等于对应宽度和高度的图片
     * 
     * @param sourceImagePath
     *            图片源地址
     * @param destinationPath
     *            压缩完图片的地址
     * @param width
     *            缩放后的宽度
     * @param height
     *            缩放后的高度
     * @param format
     *            图片格式 例如 jpg
     * @throws IOException
     * @throws Exception
     */
    public static void scaleImageToVIPByHeight(String sourceImagePath,
            String destinationPath, int width, int height, String format)
            throws Exception {

        File file = new File(sourceImagePath);
        BufferedImage bufferedImage = null;
        try {
            bufferedImage = ImageIO.read(file);
        } catch (IOException e) {
            log.error("{}", e);
        }
        double scale = height * 1.0d / bufferedImage.getHeight() * 1.0d;
        log.info("缩放比例:" + scale);
        scaleImage(sourceImagePath, destinationPath, scale, format);

    }

    /***
     * * 将图片缩放到大小等于对应宽度和高度的图片
     * 
     * @param sourceImagePath
     *            图片源地址
     * @param destinationPath
     *            压缩完图片的地址
     * @param width
     *            缩放后的宽度
     * @param height
     *            缩放后的高度
     * @param format
     *            图片格式 例如 jpg
     */
    public static void scaleImageToVIPByWidth(String sourceImagePath,
            String destinationPath, int width, int height, String format) {
        try {
            File file = new File(sourceImagePath);
            BufferedImage bufferedImage = null;
            bufferedImage = ImageIO.read(file);
            double scale = bufferedImage.getWidth() * 1.0d / width * 1.0d < 1 ? bufferedImage
                    .getWidth() * 1.0d / width * 1.0d
                    : width * 1.0d / bufferedImage.getWidth() * 1.0d;
            log.info("缩放比例:" + scale);
            scaleImage(sourceImagePath, destinationPath, scale, format);

        } catch (Exception e) {
            log.info("scaleImageWithParams方法压缩图片时出错了");
            log.error("{}", e);
        }
    }

    /**
     * * 将double类型的数据转换为int,四舍五入原则 *
     * 
     * @param sourceDouble
     * @return
     */
    private static int parseDoubleToInt(double sourceDouble) {
        int result = 0;
        result = (int) sourceDouble;
        return result;
    }

    /***
     * * @param bufferedImage 要缩放的图片对象 *
     * 
     * @param width_scale
     *            要缩放到的宽度 *
     * @param height_scale
     *            要缩放到的高度 *
     * @return 一个集合,第一个元素为宽度,第二个元素为高度
     */
    private static ArrayList<Integer> getAutoWidthAndHeight(
            BufferedImage bufferedImage, int width_scale, int height_scale) {
        ArrayList<Integer> arrayList = new ArrayList<Integer>();
        int width = bufferedImage.getWidth();
        int height = bufferedImage.getHeight();
        double scale_w = getDot2Decimal(width_scale, width);
        log.info("getAutoWidthAndHeight width=" + width + "scale_w=" + scale_w);
        double scale_h = getDot2Decimal(height_scale, height);
        if (scale_w < scale_h) {
            arrayList.add(parseDoubleToInt(scale_w * width));
            arrayList.add(parseDoubleToInt(scale_w * height));
        } else {
            arrayList.add(parseDoubleToInt(scale_h * width));
            arrayList.add(parseDoubleToInt(scale_h * height));
        }
        return arrayList;
    }

    /***
     * * 返回两个数a/b的小数点后三位的表示
     * 
     * @param a
     * @param b
     * @return
     */
    public static double getDot2Decimal(int a, int b) {
        BigDecimal bigDecimal_1 = new BigDecimal(a);
        BigDecimal bigDecimal_2 = new BigDecimal(b);
        BigDecimal bigDecimal_result = bigDecimal_1.divide(bigDecimal_2,
                new MathContext(4));
        Double double1 = new Double(bigDecimal_result.toString());
        log.info("相除后的double为:" + double1);
        return double1;
    }

    public static BufferedImage resize(BufferedImage source, int targetW,
            int targetH) {
        // targetW,targetH分别表示目标长和宽
        int type = source.getType();
        BufferedImage target = null;
        double sx = (double) targetW / source.getWidth();
        double sy = (double) targetH / source.getHeight();
        // 这里想实现在targetW,targetH范围内实现等比缩放。如果不需要等比缩放
        // 则将下面的if else语句注释即可
        if (sx > sy) {
            sx = sy;
            targetW = (int) (sx * source.getWidth());
        } else {
            sy = sx;
            targetH = (int) (sy * source.getHeight());
        }
        if (type == BufferedImage.TYPE_CUSTOM) { // handmade
            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();
        // smoother than exlax:
        g.setRenderingHint(RenderingHints.KEY_RENDERING,
                RenderingHints.VALUE_RENDER_QUALITY);
        g.drawRenderedImage(source, AffineTransform.getScaleInstance(sx, sy));
        g.dispose();
        return target;
    }

    public static boolean isPic(File file) {
        String imgeArray[] = { "bmp", "dib", "gif", "jfif", "jpe", "jpeg",
                "jpg", "png", "tif", "tiff", "ico" };
        String fileName = file.getName();
        fileName = fileName.substring(fileName.lastIndexOf(".") + 1);
        for (String suffix : imgeArray) {
            if (fileName.equals(suffix)) {
                return true;
            }
        }
        return false;
    }

    public static void createNewPic(File f, String backGroundPicPath,
            String targetPicPath) throws IOException {

        if (f.isFile()) {
            if (isPic(f)) {
                File file = new File(backGroundPicPath);
                Image img = ImageIO.read(file);
                int width = img.getWidth(null);
                int height = img.getHeight(null);
                // create target image
                BufferedImage image = new BufferedImage(width, height,
                        BufferedImage.TYPE_INT_RGB);// get a graphics pen
                Graphics g = image.createGraphics();// draw source image
                g.drawImage(img, 0, 0, width, height, null);
                // draw target logo
                BufferedImage doPic = ImageIO.read(f);
                if (doPic.getWidth() > width || doPic.getHeight() > height) {
                    resize(doPic, width, height);
                }
                BufferedImage didPic = doPic;
                int lw = didPic.getWidth(null);
                int lh = didPic.getHeight(null);
                int px_x = (width - lw) / 2;
                int px_y = (height - lh) / 2;
                g.drawImage(didPic, px_x, px_y, lw, lh, null);
                // 这里是添加水印文字// String str = "http://www.hongliang.net";
                // g.setColor(Color.red);
                // g.setFont(new Font("Courier", Font.PLAIN, 36));
                // 水印文字对准// g.drawString(str, width-400, height-60);
                g.dispose();
                FileOutputStream os = new FileOutputStream(targetPicPath
                        + f.getName());
                JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(os);
                encoder.encode(image);
                log.info("完成:" + f.getName());
                os.close();
            }
        }

    }

    /**
     * 给图片添加水印
     * 
     * @param iconPath
     *            水印图片路径
     * @param srcImgPath
     *            源图片路径
     * @param targerPath
     *            目标图片路径
     */
    public static void markImageByIcon(String iconPath, String srcImgPath,
            String targerPath) {
        markImageByIcon(iconPath, srcImgPath, targerPath, null);
    }

    /**
     * 给图片添加水印、可设置水印图片旋转角度
     * 
     * @param iconPath
     *            水印图片路径
     * @param srcImgPath
     *            源图片路径
     * @param targerPath
     *            目标图片路径
     * @param degree
     *            水印图片旋转角度
     */
    public static void markImageByIcon(String iconPath, String srcImgPath,
            String targerPath, Integer degree) {
        OutputStream os = null;
        try {
            Image srcImg = ImageIO.read(new File(srcImgPath));

            BufferedImage buffImg = new BufferedImage(srcImg.getWidth(null),
                    srcImg.getHeight(null), BufferedImage.TYPE_INT_RGB);

            // 得到画笔对象
            // Graphics g= buffImg.getGraphics();
            Graphics2D g = buffImg.createGraphics();

            // 设置对线段的锯齿状边缘处理
            g.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
                    RenderingHints.VALUE_INTERPOLATION_BILINEAR);

            g.drawImage(
                    srcImg.getScaledInstance(srcImg.getWidth(null),
                            srcImg.getHeight(null), Image.SCALE_SMOOTH), 0, 0,
                    null);

            if (null != degree) {
                // 设置水印旋转
                g.rotate(Math.toRadians(degree),
                        (double) buffImg.getWidth() / 2,
                        (double) buffImg.getHeight() / 2);
            }

            // 水印图象的路径 水印一般为gif或者png的,这样可设置透明度
            ImageIcon imgIcon = new ImageIcon(iconPath);

            // 得到Image对象。
            Image img = imgIcon.getImage();

            float alpha = 1f; // 透明度
            g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP,
                    alpha));

            // 表示水印图片的位置
            g.drawImage(img, 0, 0, null);

            g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER));

            g.dispose();

            os = new FileOutputStream(targerPath);

            // 生成图片
            ImageIO.write(buffImg, "JPG", os);
            log.info("图片完成添加Icon印章。。。。。。");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (null != os)
                    os.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    public static void createNewPic(String dir, String backGroundPicPath,
            String targetPicPath) throws IOException {

        File ML = new File(dir);
        if (ML.isDirectory()) {
            File[] files = ML.listFiles();
            for (File f : files) {
                createNewPic(f, backGroundPicPath, targetPicPath);
            }
        } else if (ML.isFile()) {
            createNewPic(ML, backGroundPicPath, targetPicPath);
        } else {
            log.info("原路径格式有误");
        }

    }

    /***
     * 图片类型格式转换
     * @param sourceImagePath 图片源路径
     * @param destImagePath 图片目标路径
     */
    public static void imageTypeConvert(String sourceImagePath,
            String destImagePath) {
        BufferedImage bufferedImage;
        try {
            File sourceFile = new File(sourceImagePath);
            bufferedImage = ImageIO.read(sourceFile);
            // create a blank, RGB, same width and height, and a white
            // background
            BufferedImage newBufferedImage = new BufferedImage(
                    bufferedImage.getWidth(), bufferedImage.getHeight(),
                    BufferedImage.TYPE_INT_RGB);
            newBufferedImage.createGraphics().drawImage(bufferedImage, 0, 0,
                    Color.WHITE, null);
            // write to jpeg file
            ImageIO.write(newBufferedImage, "jpg", new File(destImagePath));

            // 转换成功后,删除源文件
            if (sourceFile.isFile()) {
                sourceFile.delete();
            }

        } catch (IOException e) {

            e.printStackTrace();
        }

    }

    public static void main(String[] args) {

        String sourcePath = "E:\\test\\652KJ1820000F44\\target\\6.png";
        String destPath = "E:\\test\\652KJ1820000F44\\target\\6.jpg";
        imageTypeConvert(sourcePath, destPath);

    }

}
  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值