package com.trade.service.filestorage.util.watermark.impl;

import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Locale;

import javax.imageio.ImageIO;
import javax.swing.*;

import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.pdfbox.Loader;
import org.apache.pdfbox.cos.COSName;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.PDPageContentStream;
import org.apache.pdfbox.pdmodel.graphics.image.PDImageXObject;
import org.apache.pdfbox.pdmodel.graphics.state.PDExtendedGraphicsState;
import org.apache.pdfbox.util.Matrix;
import org.apache.poi.ooxml.POIXMLDocumentPart;
import org.apache.poi.openxml4j.opc.PackagePartName;
import org.apache.poi.openxml4j.opc.PackageRelationship;
import org.apache.poi.openxml4j.opc.TargetMode;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFRelation;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import com.itextpdf.text.Element;
import com.itextpdf.text.pdf.*;
import com.trade.common.exception.ServiceException;
import com.trade.service.filestorage.util.FileUtil;
import com.trade.service.filestorage.util.watermark.MakeWaterMark;
import com.trade.service.filestorage.util.watermark.PngMark;
import com.trade.service.filestorage.util.watermark.TextMark;

/**
 * @description: 制作水印实现类
 * @Author: wanglang
 * @Date: 2023/3/3 9:39
 * @Version: 1.0
 */
@Component
public class MakeWaterMarkImpl implements MakeWaterMark {

    private static final Logger logger = LogManager.getLogger(MakeWaterMarkImpl.class);

    @Override
    public void pictureMarkForPdf(String strSourcePdf, String strTargetPdf, PngMark pngMark) throws ServiceException {
        PDDocument pdDocument = null;
        try {
            File fileInputPdf = new File(strSourcePdf);
            // 打开pdf文件
            pdDocument = Loader.loadPDF(fileInputPdf);
            pdDocument.setAllSecurityToBeRemoved(true);
            PDExtendedGraphicsState pdExtGfxState = new PDExtendedGraphicsState();
            pdExtGfxState.setAlphaSourceFlag(true);
            pdExtGfxState.getCOSObject().setItem(COSName.BM, COSName.MULTIPLY);
            for (int i = 0; i < pdDocument.getNumberOfPages(); i++) {
                PDPage page = pdDocument.getPage(i);
                PDPageContentStream contentStream = new PDPageContentStream(pdDocument, page,
                        PDPageContentStream.AppendMode.APPEND, true, true);
                // 水印位置修正
                float modifyX = 0f;
                pdExtGfxState.setNonStrokingAlphaConstant(pngMark.getAlpha());
                pdExtGfxState.setAlphaSourceFlag(true);
                contentStream.setGraphicsStateParameters(pdExtGfxState);
                double dblIconLocateX;
                double dblIconLocateY;
                double dblImageWidth;
                double dblImageHeight;
                float floatIconLocateX = pngMark.getLocateX();
                if (floatIconLocateX == 0f) {
                    floatIconLocateX = 40f;
                }
                dblIconLocateX = (floatIconLocateX * 72) / 25.4;
                float floatIconLocateY = pngMark.getLocateY();
                if (floatIconLocateY == 0) {
                    floatIconLocateY = 10;
                }
                dblIconLocateY = (floatIconLocateY * 72) / 25.4;
                int intImageWidth = pngMark.getImageWidth();
                if (intImageWidth == 0) {
                    intImageWidth = 50;
                }
                dblImageWidth = (intImageWidth * 72) / 25.4;
                int intImageHeight = pngMark.getImageHeight();
                if (intImageHeight == 0) {
                    intImageHeight = 50;
                }
                dblImageHeight = (intImageHeight * 72) / 25.4;
                PDImageXObject pdImage = PDImageXObject.createFromFile(pngMark.getWaterMarkFile(), pdDocument);
                int rotation = page.getRotation();
                if (rotation > 0) {
                    float floatLocalX = page.getMediaBox().getHeight() - (float) dblIconLocateY;
                    float floatLocalY = page.getMediaBox().getWidth() - (float) dblIconLocateX - 60;
                    // 通过Matrix.getRotateInstance(angle, x, y)进行转换会围绕坐标系的原点(0，0)旋转(通常是页面的左下角)，然后平移(x，y)。
                    contentStream.transform(Matrix.getRotateInstance(Math.toRadians(rotation), (float) dblIconLocateY,
                            (float) dblIconLocateX));
                    // tx、ty为图片绘制时的左上角坐标点。（需要累加前面的偏移量）
                    contentStream.drawImage(pdImage, floatLocalX - modifyX, floatLocalY, (float) dblImageWidth,
                            (float) dblImageHeight);
                } else {
                    contentStream.transform(Matrix.getRotateInstance(Math.toRadians(0), (float) dblIconLocateX,
                            (float) dblIconLocateY));
                    // tx、ty为图片绘制时的左上角坐标点。（需要累加前面的偏移量）
                    contentStream.drawImage(pdImage, (float) dblIconLocateX - modifyX, (float) dblIconLocateY,
                            (float) dblImageWidth, (float) dblImageHeight);
                }
                // 反向旋转
                contentStream.transform(Matrix.getRotateInstance(Math.toRadians(0), -1 * (float) dblIconLocateX,
                        -1 * (float) dblIconLocateY));
                contentStream.restoreGraphicsState();
                modifyX = pngMark.getLocateX() == 0f ? 150F : pngMark.getLocateX();
            }
            pdDocument.save(strTargetPdf);
        } catch (Exception e) {
            logger.error("制作pdf文件图片水印失败,失败原因:", e);
            throw new ServiceException("制作pdf文件图片水印失败", HttpStatus.INTERNAL_SERVER_ERROR.value());
        } finally {
            if (pdDocument != null) {
                try {
                    pdDocument.close();
                } catch (IOException e) {
                    logger.error("关闭pdDocument失败,失败原因:", e);
                }
            }
        }
    }

    @Override
    public void textMarkForPdf(String strSourcePdf, String strTargetPdf, TextMark textMark) throws ServiceException {
        BufferedOutputStream bos = null;
        PdfReader reader = null;
        PdfStamper stamper = null;
        try {
            bos = new BufferedOutputStream(new FileOutputStream(strTargetPdf));
            reader = new PdfReader(strSourcePdf);
            // 针对已加密的Pdf 设置属性
            PdfReader.unethicalreading = true;
            stamper = new PdfStamper(reader, bos);
            // 获取总页数 +1, 下面从1开始遍历
            int total = reader.getNumberOfPages() + 1;
            // 使用classpath下面的字体库
            BaseFont base = BaseFont.createFont(textMark.getFontName(), "UniGB-UCS2-H", BaseFont.EMBEDDED);
            // 间隔
            int interval = -15;
            // 获取水印文字的高度和宽度
            int textH = 0;
            int textW = 0;
            JLabel label = new JLabel();
            label.setText(textMark.getWaterMarkText());
            FontMetrics metrics = label.getFontMetrics(label.getFont());
            textH = metrics.getHeight();
            textW = metrics.stringWidth(label.getText());
            // 设置水印透明度
            PdfGState gs = new PdfGState();
            gs.setFillOpacity(textMark.getAlpha());
            gs.setStrokeOpacity(0.7f);
            com.itextpdf.text.Rectangle pageSizeWithRotation;
            PdfContentByte content = null;
            for (int i = 1; i < total; i++) {
                // 在内容上方加水印
                content = stamper.getOverContent(i);
                // 在内容下方加水印
                // content = stamper.getUnderContent(i);
                content.saveState();
                content.setGState(gs);
                // 设置字体和字体大小
                content.beginText();
                content.setFontAndSize(base, textMark.getFontSize());
                // 获取每一页的高度、宽度
                pageSizeWithRotation = reader.getPageSizeWithRotation(i);
                float pageHeight = pageSizeWithRotation.getHeight();
                float pageWidth = pageSizeWithRotation.getWidth();
                // 根据纸张大小多次添加， 水印文字成30度角倾斜
                for (int height = interval + textH; height < pageHeight; height = height + textH * 6) {
                    for (int width = interval + textW; width < pageWidth + textW; width = width + textW * 2) {
                        content.showTextAligned(Element.ALIGN_LEFT, textMark.getWaterMarkText(), width - textW,
                                height - textH, textMark.getDegree());
                    }
                }
                content.endText();
            }
        } catch (Exception e) {
            logger.error("制作pdf文件文本水印失败,失败原因:", e);
            throw new ServiceException("制作pdf文件文本水印失败", HttpStatus.INTERNAL_SERVER_ERROR.value());
        } finally {
            try {
                if (stamper != null) {
                    stamper.close();
                }
                if (reader != null) {
                    reader.close();
                }
                if (bos != null) {
                    bos.close();
                }
            } catch (Exception e) {
                logger.error("制作pdf文件文本水印失关闭流失败:", e);
            }
        }
    }

    @Override
    public void pictureMarkForExcel(XSSFWorkbook workbook, String strSourceExcel, String strTargetExcel,
            PngMark pngMark) throws ServiceException {
        ByteArrayOutputStream os = null;
        ByteArrayOutputStream bos = null;
        try {
            BufferedImage image = createFileWaterMarkImage(pngMark);
            os = new ByteArrayOutputStream();
            ImageIO.write(image, "png", os);
            if (!StringUtils.isEmpty(strSourceExcel)) {
                workbook = new XSSFWorkbook(new FileInputStream(strSourceExcel));
            }
            int pictureIdx = workbook.addPicture(os.toByteArray(), Workbook.PICTURE_TYPE_PNG);
            POIXMLDocumentPart poixmlDocumentPart = workbook.getAllPictures().get(pictureIdx);
            for (int i = 0; i < workbook.getNumberOfSheets(); i++) {// 获取每个Sheet表
                XSSFSheet sheet = workbook.getSheetAt(i);
                PackagePartName ppn = poixmlDocumentPart.getPackagePart().getPartName();
                String relType = XSSFRelation.IMAGES.getRelation();
                PackageRelationship pr = sheet.getPackagePart().addRelationship(ppn, TargetMode.INTERNAL, relType,
                        null);
                sheet.getCTWorksheet().addNewPicture().setId(pr.getId());
            }
            if (!StringUtils.isEmpty(strTargetExcel)) {
                workbook.write(bos);
                bos = new ByteArrayOutputStream();
                bos.writeTo(new BufferedOutputStream(new FileOutputStream(strTargetExcel)));
            }
        } catch (IOException e) {
            logger.error("制作excel文件图片水印失败,失败原因:", e);
            throw new ServiceException("制作excel文件图片水印失败", HttpStatus.INTERNAL_SERVER_ERROR.value());
        } finally {
            try {
                if (os != null) {
                    os.close();
                }
                if (bos != null) {
                    bos.close();
                }
            } catch (IOException e) {
                logger.error("制作excel文件图片水印关闭流失败:", e);
            }
        }
    }

    @Override
    public void textMarkForExcel(XSSFWorkbook workbook, String strSourceExcel, String strTargetExcel, TextMark textMark)
            throws ServiceException {
        ByteArrayOutputStream os = null;
        try {
            BufferedImage image = createWaterMarkImage(textMark);
            os = new ByteArrayOutputStream();
            ImageIO.write(image, "png", os);
            if (!StringUtils.isEmpty(strSourceExcel)) {
                workbook = new XSSFWorkbook(new FileInputStream(strSourceExcel));
            }
            int pictureIdx = workbook.addPicture(os.toByteArray(), Workbook.PICTURE_TYPE_PNG);
            POIXMLDocumentPart poixmlDocumentPart = workbook.getAllPictures().get(pictureIdx);
            for (int i = 0; i < workbook.getNumberOfSheets(); i++) {// 获取每个Sheet表
                XSSFSheet sheet = workbook.getSheetAt(i);
                PackagePartName ppn = poixmlDocumentPart.getPackagePart().getPartName();
                String relType = XSSFRelation.IMAGES.getRelation();
                PackageRelationship pr = sheet.getPackagePart().addRelationship(ppn, TargetMode.INTERNAL, relType,
                        null);
                sheet.getCTWorksheet().addNewPicture().setId(pr.getId());
            }
            if (!StringUtils.isEmpty(strTargetExcel)) {
                ByteArrayOutputStream bos = new ByteArrayOutputStream();
                workbook.write(bos);
                bos.writeTo(new BufferedOutputStream(new FileOutputStream(strTargetExcel)));
            }
        } catch (IOException e) {
            logger.error("制作excel文件文本水印失败,失败原因:", e);
            throw new ServiceException("制作excel文件文本水印失败", HttpStatus.INTERNAL_SERVER_ERROR.value());
        } finally {
            try {
                if (os != null) {
                    os.close();
                }
            } catch (IOException e) {
                logger.error("制作excel文件文本水印关闭流失败:", e);
            }
        }
    }

    @Override
    public File pictureMarkForHtml(String path, PngMark pngMark) {
        try {
            File input = new File(path);
            Document document = Jsoup.parse(input, StandardCharsets.UTF_8.toString());
            // 添加背景图片
            document.body().getElementsByTag("body").attr("background", pngMark.getWaterMarkFile());
            Files.write(Paths.get(path), document.toString().getBytes(StandardCharsets.UTF_8));
            return new File(path);
        } catch (Exception e) {
            logger.error("制作html文件图片水印失败,失败原因:", e);
            throw new ServiceException("制作html文件图片水印失败", HttpStatus.INTERNAL_SERVER_ERROR.value());
        }
    }

    @Override
    public File pictureMarkForHtml(InputStream inputStream, PngMark pngMark, String fileName) throws ServiceException {
        ByteArrayOutputStream baos = null;
        try {
            String filePath = FileUtil.getFileOnlinePreviewPath() + File.separator + fileName + "_excel.html";
            File file = new File(filePath);
            if (!file.exists()) {
                file.createNewFile();
            }
            baos = new ByteArrayOutputStream();
            IOUtils.copy(inputStream, baos);
            FileUtils.writeByteArrayToFile(file, baos.toByteArray());
            Document document = Jsoup.parse(file, StandardCharsets.UTF_8.toString());
            // 添加背景图片
            document.body().getElementsByTag("body").attr("background", pngMark.getWaterMarkFile());
            Files.write(Paths.get(filePath), document.toString().getBytes(StandardCharsets.UTF_8));
            return file;
        } catch (Exception e) {
            logger.error("制作html文件图片水印失败,失败原因:", e);
            throw new ServiceException("制作html文件图片水印失败", HttpStatus.INTERNAL_SERVER_ERROR.value());
        } finally {
            try {
                if (baos != null) {
                    baos.close();
                }
                if (inputStream != null) {
                    inputStream.close();
                }
            } catch (IOException e) {
                logger.error("制作html文件图片水印关闭流失败:", e);
            }
        }
    }

    @Override
    public File textMarkForHtml(String path, TextMark textMark) throws ServiceException {
        try {
            File input = new File(path);
            Document document = Jsoup.parse(input, StandardCharsets.UTF_8.toString());
            createWaterMarkImage(textMark, FileUtil.getAbsoluteWaterMarkPath() + File.separator
                    + textMark.getWaterMarkName() + "_textmark.png");
            // 添加背景图片
            document.body().getElementsByTag("body").attr("background",
                    FileUtil.getWaterMarkFilePath() + File.separator + textMark.getWaterMarkName() + "_textmark.png");
            Files.write(Paths.get(path), document.toString().getBytes(StandardCharsets.UTF_8));
            return new File(path);
        } catch (Exception e) {
            logger.error("制作html文件文本水印失败,失败原因:", e);
            throw new ServiceException("制作html文件文本水印失败", HttpStatus.INTERNAL_SERVER_ERROR.value());
        }
    }

    @Override
    public File textMarkForHtml(File file, TextMark textMark) throws ServiceException {
        try {
            Document document = Jsoup.parse(file, StandardCharsets.UTF_8.toString());
            createWaterMarkImage(textMark, FileUtil.getAbsoluteWaterMarkPath() + File.separator +
                    textMark.getWaterMarkName() + "_textmark.png");
            // 添加背景图片
            document.body().getElementsByTag("body").attr("background",
                    FileUtil.getWaterMarkFilePath() + File.separator +
                            textMark.getWaterMarkName() + "_textmark.png");
            Files.write(Paths.get(file.getPath()), document.toString().getBytes(StandardCharsets.UTF_8));
            return file;
        } catch (Exception e) {
            logger.error("制作html文件文本水印失败,失败原因:", e);
            throw new ServiceException("制作html文件文本水印失败", HttpStatus.INTERNAL_SERVER_ERROR.value());
        }
    }

    @Override
    public File textMarkForHtml(InputStream inputStream, TextMark textMark, String fileName) throws ServiceException {
        ByteArrayOutputStream baos = null;
        try {
            String filePath = FileUtil.getFileOnlinePreviewPath() + File.separator + fileName + "_excel.html";
            File file = new File(filePath);
            if (!file.exists()) {
                file.createNewFile();
            }
            baos = new ByteArrayOutputStream();
            IOUtils.copy(inputStream, baos);
            FileUtils.writeByteArrayToFile(file, baos.toByteArray());
            createWaterMarkImage(textMark, FileUtil.getAbsoluteWaterMarkPath() + File.separator
                    + textMark.getWaterMarkName() + "_textmark.png");
            Document document = Jsoup.parse(file, StandardCharsets.UTF_8.toString());
            // 添加背景图片
            document.body().getElementsByTag("body").attr("background",
                    FileUtil.getWaterMarkFilePath() + File.separator + textMark.getWaterMarkName() + "_textmark.png");
            Files.write(Paths.get(filePath), document.toString().getBytes(StandardCharsets.UTF_8));
            return file;
        } catch (Exception e) {
            logger.error("制作html文件文字水印失败,失败原因:", e);
            throw new ServiceException("制作html文件文字水印失败", HttpStatus.INTERNAL_SERVER_ERROR.value());
        } finally {
            try {
                if (baos != null) {
                    baos.close();
                }
                if (inputStream != null) {
                    inputStream.close();
                }
            } catch (IOException e) {
                logger.error("制作html文件文字水印关闭流失败:", e);
            }
        }
    }

    @Override
    public void textMarkForPicture(String strSourcePdf, String strTargetPdf, TextMark textMark)
            throws ServiceException {
        try {
            File target = new File(strTargetPdf);
            if (!target.exists()) {
                target.createNewFile();
            } else {
                return;
            }
            BufferedImage bufferedImage = ImageIO.read(new File(strSourcePdf));
            createMark(bufferedImage, textMark, target, strTargetPdf);
        } catch (Exception e) {
            logger.error("制作html文件文字水印失败,失败原因:", e);
            throw new ServiceException("制作html文件文字水印失败", HttpStatus.INTERNAL_SERVER_ERROR.value());
        }
    }

    @Override
    public void textMarkForPicture(InputStream inputStream, String strTargetPdf, TextMark textMark)
            throws ServiceException {
        try {
            File target = new File(strTargetPdf);
            if (!target.exists()) {
                target.createNewFile();
            } else {
                return;
            }
            BufferedImage bufferedImage = ImageIO.read(inputStream);
            createMark(bufferedImage, textMark, target, strTargetPdf);
        } catch (Exception e) {
            logger.error("制作html文件文字水印失败,失败原因:", e);
            throw new ServiceException("制作html文件文字水印失败", HttpStatus.INTERNAL_SERVER_ERROR.value());
        }
    }

    private void createMark(BufferedImage bufferedImage, TextMark textMark, File target, String strTargetPdf)
            throws IOException {
        BufferedImage buffImg = new BufferedImage(bufferedImage.getWidth(), bufferedImage.getHeight(),
                BufferedImage.TYPE_INT_RGB);
        // 获取图片的大小
        int intImageWidth = buffImg.getWidth();
        int intImageHeight = buffImg.getHeight();
        textMark.setFontSize(40);
        // 得到画笔对象
        Graphics2D g = buffImg.createGraphics();
        // 设置对线段的锯齿状边缘处理
        g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        // 绘制原图片，作为加水印的基础图片
        g.drawImage(bufferedImage, 0, 0, bufferedImage.getWidth(), bufferedImage.getHeight(), null);
        // 设置水印旋转
        if (null != textMark.getDegree()) {
            g.rotate(Math.toRadians(textMark.getDegree()), (double) buffImg.getWidth() / 2,
                    (double) buffImg.getHeight() / 2);
        }
        // 设置水印文字颜色
        g.setColor(Color.gray);
        // 设置水印文字Font
        Font font = new Font(textMark.getFontName(), Font.PLAIN, textMark.getFontSize());
        g.setFont(font);
        // 设置水印文字透明度
        textMark.setAlpha(0.7f);
        g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, textMark.getAlpha()));
        int x = -intImageWidth / 2;
        int y;
        int markWidth = textMark.getFontSize() * getTextLength(textMark.getWaterMarkText());// 字体长度
        int markHeight = textMark.getFontSize();// 字体高度
        int intYMove = 200;
        int intXMove = 200;
        // 循环添加水印
        while (x < intImageWidth * 1.5) {
            y = -intImageHeight / 2;
            while (y < intImageHeight * 1.5) {
                g.drawString(textMark.getWaterMarkText(), x, y);
                y += markHeight + intYMove;
            }
            x += markWidth + intXMove;
        }
        // 释放资源
        g.dispose();
        // 生成图片
        try (OutputStream os = new FileOutputStream(target)) {
            if (strTargetPdf.contains(".")) {
                ImageIO.write(buffImg,
                        org.apache.commons.lang3.StringUtils.substringAfter(strTargetPdf, ".").toUpperCase(Locale.ROOT),
                        os);
            } else {
                ImageIO.write(buffImg, "JPG", os);
            }
        }
    }

    private BufferedImage createFileWaterMarkImage(PngMark pngMark) throws IOException {
        Image bufferedImage = ImageIO.read(new File(pngMark.getWaterMarkFile()));
        Font font = new Font("microsoft-yahei", Font.PLAIN, 20);
        BufferedImage image = new BufferedImage(pngMark.getImageWidth(), pngMark.getImageHeight(),
                BufferedImage.TYPE_INT_RGB);
        // 背景透明 开始
        Graphics2D g2d = image.createGraphics();
        image = g2d.getDeviceConfiguration().createCompatibleImage(image.getWidth(), image.getHeight(),
                Transparency.TRANSLUCENT);
        g2d.dispose();
        g2d = image.createGraphics();
        // 设置透明度
        g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, pngMark.getAlpha()));
        // 设置倾斜度
        g2d.rotate(Math.toRadians(-10), (double) image.getWidth() / 2, (double) image.getHeight() / 2);
        g2d.setFont(font);
        // 设置画笔字体 设定画笔颜色
        g2d.setColor(new Color(Integer.parseInt("#C5CBCF".substring(1), 16)));
        g2d.drawImage(bufferedImage, 0, 0, pngMark.getImageWidth(), pngMark.getImageHeight(), null);
        g2d.dispose();
        return image;
    }

    private BufferedImage createWaterMarkImage(TextMark textMark) {
        String[] textArray = textMark.getWaterMarkText().split("\n");
        Font font = new Font(textMark.getFontName(), Font.PLAIN, textMark.getFontSize());
        int width = 500;
        int height = 200;
        BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        // 背景透明 开始
        Graphics2D g = image.createGraphics();
        image = g.getDeviceConfiguration().createCompatibleImage(width, height, Transparency.TRANSLUCENT);
        g.dispose();
        // 背景透明 结束
        g = image.createGraphics();
        // 设定画笔颜色
        g.setColor(new Color(Integer.parseInt("#C5CBCF".substring(1), 16)));
        g.setFont(font);// 设置画笔字体
        g.shear(0.1, -0.26);// 设定倾斜度
        // 设置字体平滑
        g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        int y = 150;
        for (String s : textArray) {
            // 画出字符串
            g.drawString(s, 0, y);
            y = y + font.getSize();
        }
        // 释放画笔
        g.dispose();
        return image;
    }

    private String createWaterMarkImage(TextMark textMark, String outPath) throws Exception {
        File file = new File(outPath);
        if (!file.exists()) {
            file.createNewFile();
        } else {
            return outPath;
        }
        String[] textArray = textMark.getWaterMarkText().split("\n");
        Font font = new Font(textMark.getFontName(), Font.PLAIN, textMark.getFontSize());
        int width = 500;
        int height = 200;
        BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        // 背景透明 开始
        Graphics2D g = image.createGraphics();
        image = g.getDeviceConfiguration().createCompatibleImage(width, height, Transparency.TRANSLUCENT);
        g.dispose();
        // 背景透明 结束
        g = image.createGraphics();
        // 设定画笔颜色
        g.setColor(new Color(Integer.parseInt("#C5CBCF".substring(1), 16)));
        g.setFont(font);// 设置画笔字体
        g.shear(0.1, -0.26);// 设定倾斜度
        // 设置字体平滑
        g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        int y = 150;
        for (String s : textArray) {
            // 画出字符串
            g.drawString(s, 0, y);
            y = y + font.getSize();
        }
        // 释放画笔
        g.dispose();
        try (OutputStream os = new FileOutputStream(file)) {
            ImageIO.write(image, "png", os);
        }
        return outPath;
    }

    /**
     * 获取文本长度。汉字为1:1，英文和数字为2:1
     */
    private static int getTextLength(String text) {
        int length = text.length();
        for (int i = 0; i < text.length(); i++) {
            String s = String.valueOf(text.charAt(i));
            if (s.getBytes().length > 1) {
                length++;
            }
        }
        length = length % 2 == 0 ? length / 2 : length / 2 + 1;
        return length;
    }
}
