Java.Utils:图像处理工具类

Don’t say much, just go to the code.

package org.bood.common.utils;

import javax.imageio.ImageIO;
import javax.imageio.stream.ImageOutputStream;
import java.awt.*;
import java.awt.geom.AffineTransform;
import java.awt.image.AffineTransformOp;
import java.awt.image.BufferedImage;
import java.io.*;
import java.text.DecimalFormat;

/**
 * 图像处理工具类(本类完全可以使用,但是更加推荐ImageMagick +Jmagick </br>
 * 采用C++实现的一个类库,提供了Java的Api,非常强大和高效)</br>
 * 而且要为JVM分配较大的堆内存,否则内存溢出 </br>
 *
 * @author bood
 * @since 2020/10/16
 */
public class ImageUtils {

    private ImageUtils() {
    }

    /**
     * 缩放图片
     *
     * @param src   源文件
     * @param dest  目标文件
     * @param ratio 缩放比例,如 0.1,0.8,1.2,2.4
     * @throws IOException
     */
    public static void zoom(String src, String dest, double ratio) throws IOException {
        // 获取文件扩展名
        String suffix = src.substring(src.lastIndexOf(".") + 1);
        // 读入文件
        BufferedImage bi = ImageIO.read(new File(src));
        // 计算目标文件宽度
        int targetWidth = Integer.parseInt(new DecimalFormat("0").format(bi.getWidth() * ratio));
        // 计算目标文件高度
        int targetHeight = Integer.parseInt(new DecimalFormat("0").format(bi.getHeight() * ratio));
        // 获取BufferedImage读入的图片的一个缩放的版本
        Image image = bi.getScaledInstance(targetWidth, targetHeight, Image.SCALE_DEFAULT);
        // 创建一张空白的缓存图片
        BufferedImage target = new BufferedImage(targetWidth, targetHeight, BufferedImage.TYPE_INT_RGB);
        // 返回一张2D图像
        Graphics g = target.createGraphics();
        // 将BufferedImage读入的图片画到上一步创建的对象上
        g.drawImage(image, 0, 0, null);
        // 释放
        g.dispose();
        // 图像写入文件
        ImageIO.write(target, suffix, new File(dest));
    }

    /**
     * 切图
     *
     * @param src    源文件
     * @param dest   目标文件
     * @param startX 起点x坐标
     * @param startY 起点y坐标
     * @param endX   结束点x坐标
     * @param endY   结束点y坐标
     * @throws IOException
     */
    public static void cut(String src, String dest, int startX, int startY, int endX, int endY) throws IOException {
        // 获取文件扩展名
        String suffix = src.substring(src.lastIndexOf(".") + 1);
        // 读入文件
        BufferedImage bi = ImageIO.read(new File(src));
        // 计算宽度
        int width = Math.abs(startX - endX);
        // 计算高度
        int height = Math.abs(startY - endY);
        BufferedImage target = bi.getSubimage(startX, startY, width, height);
        ImageIO.write(target, suffix, new File(dest));
    }

    /**
     * 旋转图片
     *
     * @param src     源文件
     * @param dest    目标文件
     * @param degree  旋转角度
     * @param bgcolor 背景色,无背景色为null
     * @throws IOException
     */
    public static void rotate(String src, String dest, int degree, Color bgcolor) throws IOException {
        BufferedImage image = ImageIO.read(new File(src));
        // 原始图象的宽度
        int iw = image.getWidth();
        // 原始图象的高度
        int ih = image.getHeight();
        int w = 0;
        int h = 0;
        int x = 0;
        int y = 0;
        degree = degree % 360;
        if (degree < 0) {
            // 将角度转换到0-360度之间
            degree = 360 + degree;
        }
        // 将角度转为弧度
        double ang = Math.toRadians(degree);

        /**
         * 确定旋转后的图象的高度和宽度
         */
        if (degree == 180 || degree == 0 || degree == 360) {
            w = iw;
            h = ih;
        } else if (degree == 90 || degree == 270) {
            w = ih;
            h = iw;
        } else {
            double cosVal = Math.abs(Math.cos(ang));
            double sinVal = Math.abs(Math.sin(ang));
            w = (int) (sinVal * ih) + (int) (cosVal * iw);
            h = (int) (sinVal * iw) + (int) (cosVal * ih);
        }
        // 确定原点坐标
        x = (w / 2) - (iw / 2);
        y = (h / 2) - (ih / 2);
        BufferedImage rotatedImage = new BufferedImage(w, h, image.getType());
        Graphics2D gs = (Graphics2D) rotatedImage.getGraphics();
        if (bgcolor == null) {
            rotatedImage = gs.getDeviceConfiguration().createCompatibleImage(w, h, Transparency.TRANSLUCENT);
        } else {
            gs.setColor(bgcolor);
            // 以给定颜色绘制旋转后图片的背景
            gs.fillRect(0, 0, w, h);
        }

        AffineTransform at = new AffineTransform();
        // 旋转图象
        at.rotate(ang, w / 2, h / 2);
        at.translate(x, y);
        AffineTransformOp op = new AffineTransformOp(at,
                AffineTransformOp.TYPE_BICUBIC);
        op.filter(image, rotatedImage);
        image = rotatedImage;

        ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
        ImageOutputStream iamgeOut = ImageIO.createImageOutputStream(byteOut);

        ImageIO.write(image, "png", iamgeOut);
        InputStream is = new ByteArrayInputStream(byteOut.toByteArray());

        OutputStream os = new FileOutputStream(new File(dest));

        byte[] buffer = new byte[1024];
        int length = 0;
        while ((length = is.read(buffer)) > 0) {
            os.write(buffer, 0, length);
        }
        os.close();
        is.close();
        byteOut.close();
    }

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值