package cn.com.qmth.stmms.ms.admin.utils;

import cn.com.qmth.stmms.ms.commons.constant.SystemConstant;
import org.slf4j.LoggerFactory;

import javax.imageio.IIOImage;
import javax.imageio.ImageIO;
import javax.imageio.ImageWriteParam;
import javax.imageio.ImageWriter;
import javax.imageio.plugins.jpeg.JPEGImageWriteParam;
import javax.imageio.stream.FileImageOutputStream;
import java.awt.*;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.io.*;
import java.util.Objects;

/**
 * Created by yuanpan on 2017/12/13.
 */
public class WaterMarkUtils {
    private static final org.slf4j.Logger LOGGER = LoggerFactory.getLogger(WaterMarkUtils.class);

    public static File addTextWatermark(String text, String type, String sourcePath, String destinationPath) throws IOException {
        long start = System.currentTimeMillis();
        LOGGER.info("准备生成水印图:{}", start);
        File source = new File(sourcePath);
        File destination = new File(destinationPath);
        BufferedImage image = ImageIO.read(source);
        int width = image.getWidth();
        int height = image.getHeight();

        // determine image type and handle correct transparency
        //int imageType = "png".equalsIgnoreCase(type) ? BufferedImage.TYPE_INT_ARGB : BufferedImage.TYPE_INT_RGB;
        BufferedImage watermarked = new BufferedImage(image.getWidth(), image.getHeight(), BufferedImage.TYPE_INT_RGB);

        // initializes necessary graphic properties
        Graphics2D w = (Graphics2D) watermarked.getGraphics();
        w.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        w.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);

        w.drawImage(image.getScaledInstance(image.getWidth(), image.getHeight(), Image.SCALE_SMOOTH), 0, 0, null);
        AlphaComposite alphaChannel = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.4f);
        w.setComposite(alphaChannel);
        w.setColor(Color.red);
        w.setFont(new Font(Font.SANS_SERIF, Font.BOLD, 60));
        FontMetrics fontMetrics = w.getFontMetrics();
        Rectangle2D rect = fontMetrics.getStringBounds(text, w);

        // calculate center of the image
//        int x = (image.getWidth() - (int) rect.getWidth()) / 2;
//        int y = image.getHeight() / 2;

        int x = 0;
        int y = image.getHeight() - (int) rect.getHeight() + 50;

        // add text overlay to the image
        w.drawString(text, x, y);
        //ImageIO.write(watermarked, type, destination);
        //w.dispose();


        JPEGImageWriteParam jepgParams = new JPEGImageWriteParam(null);
        jepgParams.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
        jepgParams.setCompressionQuality(1f);
        final ImageWriter writer = ImageIO.getImageWritersByFormatName("jpg").next();
        writer.setOutput(new FileImageOutputStream(destination));
        writer.write(null, new IIOImage(watermarked, null, null), jepgParams);
        writer.dispose();


        w.dispose();


//        FileOutputStream fos = new FileOutputStream(destination);
//        JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(fos);
//        encoder.encode(watermarked);
//        fos.flush();
//        fos.close();
        long end = System.currentTimeMillis();
        LOGGER.info("生成水印图耗时：{}", (end - start) / 1000 + "s");
        return destination;
    }


    /**
     * @param srcImgPath       源图片路径
     * @param tarImgPath       保存的图片路径
     * @param waterMarkContent 水印内容
     * @param markContentColor 水印颜色
     * @param font             水印字体
     */
    public static void addWaterMark(String srcImgPath, String tarImgPath, String waterMarkContent, Color markContentColor, Font font) {

        try {
            // 读取原图片信息
            File srcImgFile = new File(srcImgPath);//得到文件
            Image srcImg = ImageIO.read(srcImgFile);//文件转化为图片
            int srcImgWidth = srcImg.getWidth(null);//获取图片的宽
            int srcImgHeight = srcImg.getHeight(null);//获取图片的高
            // 加水印
            BufferedImage bufImg = new BufferedImage(srcImgWidth, srcImgHeight, BufferedImage.TYPE_INT_RGB);
            Graphics2D g = bufImg.createGraphics();
            g.drawImage(srcImg, 0, 0, srcImgWidth, srcImgHeight, null);
            g.setColor(markContentColor); //根据图片的背景设置水印颜色
            g.setFont(font);              //设置字体

            //设置水印的坐标
//            int x = srcImgWidth - getWatermarkWidth(waterMarkContent, g);
//            int y = getWatermarkHeight(g);
            int x = 0;
            int y = srcImgHeight - getWatermarkHeight(g) + 50;
//            int y = srcImgHeight;
            g.drawString(waterMarkContent, x, y);  //画出水印
            g.dispose();
            // 输出图片
            FileOutputStream outImgStream = new FileOutputStream(tarImgPath);
            ImageIO.write(bufImg, "jpg", outImgStream);
            System.out.println("添加水印完成");
            outImgStream.flush();
            outImgStream.close();

        } catch (Exception e) {
            // TODO: handle exception
        }
    }

    private static int getWatermarkWidth(String waterMarkContent, Graphics2D g) {
        return g.getFontMetrics(g.getFont()).charsWidth(waterMarkContent.toCharArray(), 0, waterMarkContent.length());
    }

    private static int getWatermarkHeight(Graphics2D g) {
        return g.getFontMetrics(g.getFont()).getHeight();
    }

    /**
     * 生成水印图(新)
     *
     * @param md5
     * @param text
     * @param type
     * @param sourcePath
     * @param destinationPath
     * @throws IOException
     */
    public static void addTextWatermarkNew(String md5, String text, String type, String sourcePath, String destinationPath) throws IOException {
        long start = System.currentTimeMillis();
        LOGGER.info("准备生成水印图:{}", start);
        String sourceTempPath = sourcePath + "temp.jpg";
        //读取指定路径下面的文件
        InputStream inputStream = new FileInputStream(sourcePath + ".jpg");
        OutputStream outputStream = new FileOutputStream(sourceTempPath);
        SystemConstant.writeStream(inputStream, outputStream);
        inputStream.close();
        outputStream.flush();
        outputStream.close();
        File source = new File(sourceTempPath);
        File destinationTemp = new File(destinationPath + "temp.jpg");
        BufferedImage image = ImageIO.read(source);
        int width = image.getWidth();
        int height = image.getHeight();

        BufferedImage watermarked = new BufferedImage(image.getWidth(), image.getHeight(), BufferedImage.TYPE_INT_RGB);

        Graphics2D w = (Graphics2D) watermarked.getGraphics();
        w.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        w.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);

        w.drawImage(image.getScaledInstance(image.getWidth(), image.getHeight(), Image.SCALE_SMOOTH), 0, 0, null);
        AlphaComposite alphaChannel = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.4f);
        w.setComposite(alphaChannel);
        w.setColor(Color.red);
        w.setFont(new Font(Font.SANS_SERIF, Font.BOLD, 60));
        FontMetrics fontMetrics = w.getFontMetrics();
        Rectangle2D rect = fontMetrics.getStringBounds(text, w);

        int x = 0;
        int y = image.getHeight() - (int) rect.getHeight() + 50;

        w.drawString(text, x, y);

        JPEGImageWriteParam jepgParams = new JPEGImageWriteParam(null);
        jepgParams.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
        jepgParams.setCompressionQuality(1f);
        final ImageWriter writer = ImageIO.getImageWritersByFormatName("jpg").next();
        writer.setOutput(new FileImageOutputStream(destinationTemp));
        writer.write(null, new IIOImage(watermarked, null, null), jepgParams);
        writer.dispose();
        w.dispose();

        InputStream inputStream1 = new FileInputStream(destinationTemp);
        File watermarkFile = new File(destinationPath + ".jpg");
        LOGGER.info("watermark存放目录:{}", watermarkFile.getPath());
        OutputStream outputStream1 = new FileOutputStream(watermarkFile);
        SystemConstant.writeStream(inputStream1, outputStream1);
        inputStream1.close();
        outputStream1.flush();
        outputStream1.close();

        if (Objects.nonNull(source) && source.exists()) {
            source.delete();
        }
        if (Objects.nonNull(destinationTemp) && destinationTemp.exists()) {
            destinationTemp.delete();
        }
        long end = System.currentTimeMillis();
        LOGGER.info("生成水印图耗时：{}", (end - start) / 1000 + "s");
    }
}
