package com.huatek.busi.common.util;

import org.w3c.dom.Element;

import javax.imageio.IIOImage;
import javax.imageio.ImageIO;
import javax.imageio.ImageTypeSpecifier;
import javax.imageio.ImageWriter;
import javax.imageio.metadata.IIOMetadata;
import javax.imageio.plugins.jpeg.JPEGImageWriteParam;
import javax.imageio.stream.ImageOutputStream;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 图片 缩放工具
 */
public class ResizeImageUtil {


    public static BufferedImage resizeImage(BufferedImage im, float resizeTimes) {
        /*原始图像的宽度和高度*/
        int width = im.getWidth();
        int height = im.getHeight();

        /*调整后的图片的宽度和高度*/
        int toWidth = (int) (Float.parseFloat(String.valueOf(width)) / resizeTimes);
        int toHeight = (int) (Float.parseFloat(String.valueOf(height)) / resizeTimes);

        /*新生成结果图片*/
        BufferedImage result = new BufferedImage(toWidth, toHeight, BufferedImage.TYPE_INT_RGB);

        result.getGraphics().drawImage(im.getScaledInstance(toWidth, toHeight, java.awt.Image.SCALE_SMOOTH), 0, 0, null);
        return result;
    }

    /**
     * @param im          原始图像
     * @param resizeTimes 倍数,比如0.5就是缩小一半,0.98等等double类型
     * @return 返回处理后的图像
     */
    public static BufferedImage zoomImage(BufferedImage im, float resizeTimes) {
        /*原始图像的宽度和高度*/
        int width = im.getWidth();
        int height = im.getHeight();

        /*调整后的图片的宽度和高度*/
        int toWidth = (int) (Float.parseFloat(String.valueOf(width)) * resizeTimes);
        int toHeight = (int) (Float.parseFloat(String.valueOf(height)) * resizeTimes);

        /*新生成结果图片*/
        BufferedImage result = new BufferedImage(toWidth, toHeight, BufferedImage.TYPE_INT_RGB);

        result.getGraphics().drawImage(im.getScaledInstance(toWidth, toHeight, java.awt.Image.SCALE_SMOOTH), 0, 0, null);
        return result;
    }

    /**
     * @param path 要转化的图像的文件夹,就是存放图像的文件夹路径
     * @param type 图片的后缀名组成的数组
     * @return
     */
    public static List<BufferedImage> getImageList(String path, String[] type) throws IOException {
        Map<String, Boolean> map = new HashMap<String, Boolean>();
        for (String s : type) {
            map.put(s, true);
        }
        List<BufferedImage> result = new ArrayList<BufferedImage>();
        File[] fileList = new File(path).listFiles();
        for (File f : fileList) {
            if (f.length() == 0)
                continue;
            if (map.get(getExtension(f.getName())) == null)
                continue;
            if (getExtension(f.getName()).equals("pdf") || getExtension(f.getName()).equals("PDF")) {
                result.add(PDF2ImageUtil.PDF2ImageUtil(f));
            } else {
                result.add(ImageIO.read(f));
            }

        }
        return result;
    }

    /**
     * 把图片写到磁盘上
     *
     * @param im
     * @param path     eg: C://home// 图片写入的文件夹地址
     * @param fileName DCM1987.jpg  写入图片的名字
     * @return
     */
    public static boolean writeToDisk(BufferedImage im, String path, String fileName) {
        File f = new File(path + fileName);
        String fileType = getExtension(fileName);
        if (fileType == null) {
            return false;
        }
        try {
            ImageIO.write(im, fileType, f);
            im.flush();
            return true;
        } catch (IOException e) {
            return false;
        }
    }


    public static boolean writeHighQuality(BufferedImage im, String fileFullPath) {
        try {
            /*输出到文件流*/
            FileOutputStream newimage = new FileOutputStream(fileFullPath + System.currentTimeMillis() + ".jpg");
//            JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(newimage);
//            JPEGEncodeParam jep = JPEGCodec.getDefaultJPEGEncodeParam(im);
//            /* 压缩质量 */
//            jep.setQuality(10f, true);
//            encoder.encode(im, jep);
           /*近JPEG编码*/
            saveAsJPEG(100, im, 10, newimage);
            newimage.close();
            return true;
        } catch (Exception e) {
            return false;
        }
    }

    /**
     * 以JPEG编码保存图片
     *
     * @param dpi             分辨率
     * @param image_to_save   要处理的图像图片
     * @param JPEGcompression 压缩比
     * @param fos             文件输出流
     * @throws IOException
     */
    public static void saveAsJPEG(Integer dpi, BufferedImage image_to_save, float JPEGcompression, FileOutputStream fos) throws IOException {

        ImageWriter imageWriter = ImageIO.getImageWritersBySuffix("jpg").next();
        ImageOutputStream ios = ImageIO.createImageOutputStream(fos);
        imageWriter.setOutput(ios);
        //and metadata
        IIOMetadata imageMetaData = imageWriter.getDefaultImageMetadata(new ImageTypeSpecifier(image_to_save), null);
        if (dpi != null && !dpi.equals("")) {
            Element tree = (Element) imageMetaData.getAsTree("javax_imageio_jpeg_image_1.0");
            Element jfif = (Element) tree.getElementsByTagName("app0JFIF").item(0);
            jfif.setAttribute("Xdensity", Integer.toString(dpi));
            jfif.setAttribute("Ydensity", Integer.toString(dpi));
        }

        if (JPEGcompression >= 0 && JPEGcompression <= 1f) {

            JPEGImageWriteParam jpegParams = (JPEGImageWriteParam) imageWriter.getDefaultWriteParam();
            jpegParams.setCompressionMode(JPEGImageWriteParam.MODE_EXPLICIT);
            jpegParams.setCompressionQuality(JPEGcompression);
        }

        imageWriter.write(imageMetaData, new IIOImage(image_to_save, null, null), null);
        ios.close();
        imageWriter.dispose();

    }

    /**
     * 返回文件的文件后缀名
     *
     * @param fileName
     * @return
     */
    public static String getExtension(String fileName) {
        try {
            return fileName.split("\\.")[fileName.split("\\.").length - 1];
        } catch (Exception e) {
            return null;
        }
    }

    public static void main(String[] args) throws Exception {

        String inputFoler = "d:\\cameraImage";
         /*这儿填写你存放要缩小图片的文件夹全地址*/
        String outputFolder = "d:\\output\\";
        /*这儿填写你转化后的图片存放的文件夹*/
        float times = 1f;
        /*这个参数是要转化成的倍数,如果是1就是转化成1倍*/
//        ResizeImage r = new ResizeImage();
        List<BufferedImage> imageList = ResizeImageUtil.getImageList(inputFoler, new String[]{"pdf"});
        for (BufferedImage i : imageList) {
            ResizeImageUtil.writeHighQuality(ResizeImageUtil.zoomImage(i, times), outputFolder);
        }
    }


}
