package com.upload.util;

import com.upload.entity.Local;
import org.springframework.web.multipart.MultipartFile;

import javax.imageio.ImageIO;
import javax.imageio.stream.ImageOutputStream;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;

public class WatermarkUtil {

    /**
     * 加图片水印
     *
     * @param bufImg  --BufferedImage  用来画图的宽高跟需要加水印的图片一样的空白图
     * @param img     --需要加水印的图片
     * @param markImg --水印图片
     * @param width   --水印图片宽
     * @param height  --水印图片高
     * @param x       --水印相对于底片的x轴坐标(PS:左上角为(0,0))
     * @param y       --水印相对于底片的y轴坐标(PS:左上角为(0,0))
     */
    public static void markPic(BufferedImage bufImg, Image img, Image markImg, int width, int height, int x, int y) {
        //取到画笔
        Graphics2D g = bufImg.createGraphics();
        //画底片
        g.drawImage(img, 0, 0, bufImg.getWidth(), bufImg.getHeight(), null);
        //画水印位置
        g.drawImage(markImg, x, y, width, height, null);
        g.dispose();
    }


    /**
     * 加文字水印
     *
     * @param bufImg --BufferedImage  用来画图的宽高跟需要加水印的图片一样的空白图
     * @param img    --需要加水印的图片
     * @param text   --水印文字
     * @param font   --字体
     * @param color  --颜色
     * @param x      --水印相对于底片的x轴坐标(PS:左上角为(0,0))
     * @param y      --水印相对于底片的y轴坐标(PS:左上角为(0,0))
     */
    public static void markWord(BufferedImage bufImg, Image img, String text, Font font, Color color, int x, int y) {
        //取到画笔
        Graphics2D g = bufImg.createGraphics();
        //画底片
        g.drawImage(img, 0, 0, bufImg.getWidth(), bufImg.getHeight(), null);
        g.setColor(color);
        g.setFont(font);
        //位置
        g.drawString(text, x, y);
        g.dispose();
    }

    public static void markPicAndWord(BufferedImage bufImg, Image img, Image markImg, Local local) {
        //取到画笔
        Graphics2D g = bufImg.createGraphics();
        //画底片
        g.drawImage(img, 0, 0, bufImg.getWidth(), bufImg.getHeight(), null);
        //画水印图片
        g.drawImage(markImg, local.getMarkX(), local.getMarkY(), local.getMarkWidth(), local.getMarkHeight(), null);
        //画水印文字
        g.setColor(local.getColor());
        g.setFont(local.getFont());
        g.drawString(local.getRegistrationCode(), local.getRegistrationCodeX(), local.getRegistrationCodeY());
        g.drawString(local.getDateTime(), local.getDateTimeX(), local.getDateTimeY());
        g.drawString(local.getWorkerName(), local.getWorkerNameX(), local.getWorkerNameY());

        g.dispose();
    }

    /**
     * 单文件返回水印图片byte[]数组
     *
     * @param multipartFile    待加水印的文件
     * @param watermarkImage   水印图片本地图片地址
     * @param workerName       水印文字
     * @param registrationCode 水印文字
     * @return 操作结果
     * @throws IOException
     */
    public static byte[] pressImageAndWorld(MultipartFile multipartFile, String watermarkImage, String workerName, String registrationCode) throws IOException {
        String originFileName = multipartFile.getOriginalFilename();
        int lastSplit = originFileName.lastIndexOf(".");
        String suffix = originFileName.substring(lastSplit + 1);
        return press(watermarkImage, workerName, registrationCode, multipartFile, suffix);
    }

    /**
     * 多文件返回图片 ArrayList<byte[]> 数组
     *
     * @param multipartFiles   待加水印的文件
     * @param watermarkImage   水印图片本地图片地址
     * @param workerName       水印文字
     * @param registrationCode 水印文字
     * @return 操作结果
     * @throws IOException
     */
    public static ArrayList<byte[]> pressImageAndWorld(MultipartFile[] multipartFiles, String watermarkImage, String workerName, String registrationCode) throws IOException {
        ArrayList<byte[]> bytes = new ArrayList<>();
        for (MultipartFile multipartFile : multipartFiles) {
            String originFileName = multipartFile.getOriginalFilename();
            int lastSplit = originFileName.lastIndexOf(".");
            String suffix = originFileName.substring(lastSplit + 1);
            bytes.add(press(watermarkImage, workerName, registrationCode, multipartFile, suffix));
        }
        return bytes;
    }

    private static byte[] press(String watermarkImage, String workerName, String registrationCode, MultipartFile multipartFile, String suffix) throws IOException {
        // 获取待加水印图片
        InputStream inputImg = multipartFile.getInputStream();
        Image img = ImageIO.read(inputImg);
        // 获取水印图片
        Image mark = ImageIO.read(new FileInputStream(new File(watermarkImage)));
        //获取待加水印图片大小
        int imgWidth = img.getWidth(null);
        int imgHeight = img.getHeight(null);
        //把待加水印的图片读入缓存
        BufferedImage bufImg = new BufferedImage(imgWidth, imgHeight, BufferedImage.TYPE_INT_RGB);
        //设置字体
        int fontSize = imgWidth / 40;
        Font font = new Font("宋体", Font.BOLD, fontSize);
        double registrationCodeX = imgWidth - (registrationCode.length() * fontSize * 0.56);
        //创建输出流
        ByteArrayOutputStream bs = new ByteArrayOutputStream();
        ImageOutputStream imageOutputStream = ImageIO.createImageOutputStream(bs);
        //设置图片和文字位置,水印图片大小
        int markWidth = imgWidth / 4;
        int markHeight = (imgWidth * mark.getHeight(null)) / (4 * mark.getWidth(null));
        //组装要画的数据
        String now = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd hh:mm:ss"));
        Local local = new Local(
                workerName, 0, imgHeight - fontSize * 2,
                now, 0, imgHeight,
                registrationCode, (int) registrationCodeX, imgHeight - markHeight - fontSize,
                markWidth, markHeight, imgWidth - markWidth, imgHeight - markHeight,
                multipartFile, font, new Color(42, 148, 188));
        //调用画图片和文字的方法
        markPicAndWord(bufImg, img, mark, local);
        ImageIO.write(bufImg, suffix, imageOutputStream);

        //bs.writeTo(fileOutputStream);
        byte[] bytes = bs.toByteArray();
        bs.close();
        inputImg.close();
        imageOutputStream.close();
        return bytes;
    }
}
