package com.inkasso.factoring.file.util;


 import net.coobird.thumbnailator.Thumbnails;

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

  /**
   * 图片处理工具类.
   *
   * @author admin
   * @date 2022-09-23 17:10
   */
  public class PicUtils {

    public static void main(String[] args) {

      PicUtils.compressPicForScale("D:\\fb50221b2f19381bc34dfecbd00e8342.jpg", "D:\\test.jpg",
              2000, 0.9); // 图片小于1000kb
    }

    /**
     * 根据指定大小和指定精度压缩图片
     *
     * @param srcPath      源图片地址
     * @param desPath      目标图片地址
     * @param desFileSize  指定图片大小，单位kb（压缩到多大以内）
     * @param accuracy     精度，递归压缩的比率，建议小于0.9
     * @return 目标文件路径
     */
    public static String compressPicForScale(String srcPath, String desPath, long desFileSize, double accuracy) {
      if (!new File(srcPath).exists()) {
        return null;
      }
      try {
        File srcFile = new File(srcPath);
        long srcFileSize = srcFile.length();
        System.out.println("源图片：" + srcPath + "，大小：" + srcFileSize / 1024 + "kb");
        //获取图片信息
        BufferedImage bim = ImageIO.read(srcFile);
        int srcWidth = bim.getWidth();
        int srcHeight = bim.getHeight();

        //先转换成jpg
        Thumbnails.Builder<File> builder = Thumbnails.of(srcFile).outputFormat("jpg");

        // 指定大小（宽或高超出会才会被缩放）
//        if (srcWidth > desMaxWidth || srcHeight > desMaxHeight) {
//          builder.size(desMaxWidth, desMaxHeight);
//        } else {
//          //宽高均小，指定原大小
//          builder.size(srcWidth, srcHeight);
//        }
        builder.size(srcWidth, srcHeight);

        // 写入到内存
        ByteArrayOutputStream bos = new ByteArrayOutputStream(); //字节输出流（写入到内存）
        builder.toOutputStream(bos);

        // 递归压缩，直到目标文件大小小于desFileSize
        byte[] bytes = compressPicCycle(bos.toByteArray(), desFileSize, accuracy);

        // 输出到文件
        File desFile = new File(desPath);
        FileOutputStream fos = new FileOutputStream(desFile);
        fos.write(bytes);
        fos.close();

        System.out.println("目标图片：" + desPath + "，大小" + desFile.length() / 1024 + "kb");
        System.out.println("图片压缩完成！");
      } catch (Exception e) {
        return null;
      }
      return desPath;
    }

    private static byte[] compressPicCycle(byte[] bytes, long desFileSize, double accuracy) throws IOException {
      // File srcFileJPG = new File(desPath);
      long srcFileSizeJPG = bytes.length;
      // 2、判断大小，如果小于500kb，不压缩；如果大于等于500kb，压缩
      if (srcFileSizeJPG <= desFileSize * 1024) {
        return bytes;
      }
      // 计算宽高
      BufferedImage bim = ImageIO.read(new ByteArrayInputStream(bytes));
      int srcWidth = bim.getWidth();
      int srcHeight = bim.getHeight();
      int desWidth = new BigDecimal(srcWidth).multiply(new BigDecimal(accuracy)).intValue();
      int desHeight = new BigDecimal(srcHeight).multiply(new BigDecimal(accuracy)).intValue();

      ByteArrayOutputStream bos = new ByteArrayOutputStream(); //字节输出流（写入到内存）
      Thumbnails.of(new ByteArrayInputStream(bytes)).size(desWidth, desHeight).outputQuality(accuracy).toOutputStream(bos);
      return compressPicCycle(bos.toByteArray(), desFileSize, accuracy);
    }
}
