图片处理工具类(裁剪,按固定宽高比裁剪,base64字符串转图片)

package com.common.utils;

import com.drew.imaging.ImageMetadataReader;
import com.drew.metadata.Directory;
import com.drew.metadata.Metadata;
import com.drew.metadata.exif.ExifDirectory;
import com.sun.image.codec.jpeg.JPEGCodec;
import com.sun.image.codec.jpeg.JPEGEncodeParam;
import com.sun.image.codec.jpeg.JPEGImageEncoder;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import sun.misc.BASE64Decoder;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;

public class ImageUtils {

    private static Logger log = LoggerFactory.getLogger(ImageUtils.class);

    /**
     * 直接指定压缩后的宽高:
     * (先保存原文件,再压缩、上传)
     * 壹拍项目中用于二维码压缩
     * @param oldFile 要进行压缩的文件全路径
     * @param width 压缩后的宽
     * @param height 压缩后的高
     * @param quality 图片质量
     * @return 返回压缩后的文件的全路径
     */
    public static String compressAspectImage(String oldFile, int width, int height, float quality, String fileName) {
        if (oldFile == null) {
            return null;
        }
        File imgFile = new File(oldFile);
        String newImage = null;
        if (imgFile.exists()) {
            try {
                /**对服务器上的临时文件进行处理 */
                Image srcFile = ImageIO.read(new File(oldFile));
                int w = ((BufferedImage) srcFile).getWidth();
                int h = ((BufferedImage) srcFile).getHeight();
                if (width > w) {
                    width = w;
                }
                if (height > h) {
                    height = h;
                }
                /** 宽,高设定 */
                BufferedImage tag = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
                tag.getGraphics().drawImage(srcFile, 0, 0, width, height, null);
                /** 压缩后的文件名 */
                String p = imgFile.getPath();
                newImage = p.substring(0, p.lastIndexOf(File.separator)) + File.separator + fileName;
                /** 压缩之后临时存放位置 */
                FileOutputStream out = new FileOutputStream(newImage);
                JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);
                JPEGEncodeParam jep = JPEGCodec.getDefaultJPEGEncodeParam(tag);
                /** 压缩质量 */
                jep.setQuality(quality, true);
                encoder.encode(tag, jep);
                out.close();
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return newImage;
    }

    /**
     * 裁剪固定宽高比图片
     * @param oldFile 源文件
     * @param aspectRatio 宽高比
     * @return
     */
    public static String cutAspectRatioImage(String oldFile, double aspectRatio, float quality, String fileName) {
        if (oldFile == null) {
            return null;
        }
        File imgFile = new File(oldFile);
        String cutImage = "";
        if (imgFile.exists()) {
            try {
                Image srcFile = ImageIO.read(imgFile);
                int width = ((BufferedImage) srcFile).getWidth();
                int height = ((BufferedImage) srcFile).getHeight();
                // 1.裁剪成临时文件
                BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
                bufferedImage.getGraphics().drawImage(srcFile, 0, 0, width, height, null);
                int startX = 0;
                int startY = 0;
                int endX = width;
                int endY = height;
                // 获取短边
                // 1.假如图片的宽高比比需要的宽高比要大,则高是短边,按高为参照计算宽
                if ((double)width / height >= aspectRatio)
                {
                    int w = new Double(height * aspectRatio).intValue();
                    int offsetWidth = (width - w) / 2;
                    startX = offsetWidth;
                    endX = endX - offsetWidth;
                }
                // 2.假如图片的宽高比比需要的宽高比要小,则宽是短边,按宽为参照计算高
                else
                {
                    int h = new Double(width / aspectRatio).intValue();
                    int offsetHeight = (height - h) / 2;
                    startY = offsetHeight;
                    endY = endY - offsetHeight;
                }
                if (startX == -1) {
                    startX = 0;
                }
                if (startY == -1) {
                    startY = 0;
                }
                if (endX == -1) {
                    endX = width - 1;
                }
                if (endY == -1) {
                    endY = height - 1;
                }
                String p = imgFile.getPath();
                cutImage = p.substring(0, p.lastIndexOf(File.separator)) + File.separator + fileName;
                BufferedImage result = new BufferedImage(endX - startX, endY - startY, Image.SCALE_SMOOTH);
                for (int x = startX; x < endX; ++x) {
                    for (int y = startY; y < endY; ++y) {
                        int rgb = bufferedImage.getRGB(x, y);
                        result.setRGB(x - startX, y - startY, rgb);
                    }
                }
                FileOutputStream cutOut = new FileOutputStream(cutImage);
                JPEGImageEncoder cutEncoder = JPEGCodec.createJPEGEncoder(cutOut);
                JPEGEncodeParam cutJep = JPEGCodec.getDefaultJPEGEncodeParam(result);
                cutJep.setQuality(quality, true);
                cutEncoder.encode(result, cutJep);
                cutOut.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return cutImage;
    }


    /**
     * 调整图片角度
     * @param src
     * @param angel
     * @return
     */
    private static BufferedImage rotate(Image src, int angel) {
        int src_width = src.getWidth(null);
        int src_height = src.getHeight(null);
        // calculate the new image size
        Rectangle rect_des = calcRotatedSize(new Rectangle(new Dimension(src_width, src_height)), angel);

        BufferedImage res = null;
        res = new BufferedImage(rect_des.width, rect_des.height,
                BufferedImage.TYPE_INT_RGB);
        Graphics2D g2 = res.createGraphics();
        // transform
        g2.translate((rect_des.width - src_width) / 2,
                (rect_des.height - src_height) / 2);
        g2.rotate(Math.toRadians(angel), src_width / 2, src_height / 2);

        g2.drawImage(src, null, null);
        return res;
    }

    /**
     * 计算旋转参数
     * @param src
     * @param angel
     * @return
     */
    private static Rectangle calcRotatedSize(Rectangle src, int angel) {
        // if angel is greater than 90 degree, we need to do some conversion
        if (angel >= 90) {
            if(angel / 90 % 2 == 1){
                int temp = src.height;
                src.height = src.width;
                src.width = temp;
            }
            angel = angel % 90;
        }

        double r = Math.sqrt(src.height * src.height + src.width * src.width) / 2;
        double len = 2 * Math.sin(Math.toRadians(angel) / 2) * r;
        double angel_alpha = (Math.PI - Math.toRadians(angel)) / 2;
        double angel_dalta_width = Math.atan((double) src.height / src.width);
        double angel_dalta_height = Math.atan((double) src.width / src.height);

        int len_dalta_width = (int) (len * Math.cos(Math.PI - angel_alpha
                - angel_dalta_width));
        int len_dalta_height = (int) (len * Math.cos(Math.PI - angel_alpha
                - angel_dalta_height));
        int des_width = src.width + len_dalta_width * 2;
        int des_height = src.height + len_dalta_height * 2;
        return new Rectangle(new Dimension(des_width, des_height));
    }

    /**
     * 获得图片调整角度
     * @param imgFile
     * @return
     */
    private static Integer getImgRotateAngle(String imgFile){
        Integer angel = 0;
        Metadata metadata = null;
        try{
            if(StringUtils.isBlank(imgFile))
                return angel;
            File _img_file_ = new File(imgFile);
            if(!_img_file_.exists())
                return angel;
            metadata = ImageMetadataReader.readMetadata(_img_file_);
            Directory directory = metadata.getDirectory(ExifDirectory.class);
            if(directory != null && directory.containsTag(ExifDirectory.TAG_ORIENTATION)){
                int orientation = directory.getInt(ExifDirectory.TAG_ORIENTATION);
                // 原图片的方向信息
                if(6 == orientation)
                {
                    //6旋转90
                    angel = 90;
                }
                else if(3 == orientation)
                {
                    //3旋转180
                    angel = 180;
                }
                else if(8 == orientation)
                {
                    //8旋转90
                    angel = 270;
                }
            }
        }catch(Exception e){
            e.printStackTrace();
        }
        return angel;
    }

    /**
     * 调整图片角度
     * @param imgFile
     */
    public static void rotateImage(String imgFile){
        try {
            if(!StringUtils.isBlank(imgFile)){
                File _img_file_ = new File(imgFile);
                if(_img_file_.exists()){
                    Integer angel = getImgRotateAngle(imgFile);
                    if(angel == 0)return;
                    BufferedImage src = ImageIO.read(_img_file_);
                    BufferedImage des = rotate(src, 0);
                    ImageIO.write(des,"jpg", _img_file_);
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static boolean base64ToImage(String imageSavePath, String base64str){

        // 图像数据为空
        if (StringUtils.isEmpty(base64str)) {
            log.error("base64ToImage base64Str isEmpty");
            return false;
        }

        File file = new File(imageSavePath);
        if (!file.getParentFile().exists()) {
            file.getParentFile().mkdirs();
        }

        BASE64Decoder decoder = new BASE64Decoder();
        try {
            // Base64解码
            byte[] b = decoder.decodeBuffer(base64str);
            for (int i = 0; i < b.length; ++i) {
                // 调整异常数据
                if (b[i] < 0) {
                    b[i] += 256;
                }
            }

            OutputStream out = new FileOutputStream(imageSavePath);
            out.write(b);
            out.flush();
            out.close();

            return true;
        } catch (Exception e) {
            log.error("base64ToImage exception: {}", e.getMessage());
            return false;
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值