Graphics2D繪製水印圖;包含在原文件上添加文字水印(文字帶背景顏色)和圖片水印

package com.epean.trade.lms.util;

import com.alibaba.fastjson.JSONObject;
import com.epean.trade.component.entity.watermark.SysWatermark;
import com.epean.trade.component.enums.WatermarkCodeEnum;
import com.epean.trade.component.mapper.watermark.SysWatermarkMapper;
import com.epean.trade.framework.exception.BaseAppException;
import com.google.common.io.FileBackedOutputStream;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import sun.font.FontDesignMetrics;
import tk.mybatis.mapper.entity.Example;

import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.Serializable;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 添加水印工具類
 * Created by IntelliJ IDEA.
 * Date: 2019-07-29
 * Since: JDK1.8
 */
public class WatermarkUtils implements Serializable {

    private static final long serialVersionUID = -184614654848842705L;

    private static final Logger logger = LoggerFactory.getLogger(WatermarkUtils.class);


    /**
     * 添加水印
     *
     * @param srcImagePath       需要添加水印的文件(文件全路徑)
     * @param watermarkIds       水印的ids (多個id使用 "," 分隔)
     * @param imgPrefix          水印圖片所在位置前綴
     * @param sysWatermarkMapper 水印管理mapper對象
     * @return 返回ftp需要的輸入流
     */
    public static InputStream addWatermark(String srcImagePath, String watermarkIds, String imgPrefix, SysWatermarkMapper sysWatermarkMapper) throws Exception {
        if (StringUtils.isBlank(srcImagePath)) throw new BaseAppException(WatermarkCodeEnum.ERROR_SRC_CODE.getValue());
        String fileSuffix = srcImagePath.substring(srcImagePath.lastIndexOf(".") + 1);
        if (StringUtils.isBlank(watermarkIds)) throw new BaseAppException(WatermarkCodeEnum.ERROR_ID_CODE.getValue());
        List<String> ids = Arrays.stream(watermarkIds.split(",")).collect(Collectors.toList());
        Example example = new Example(SysWatermark.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andIn("id", ids);
        criteria.andEqualTo("status", 1);
        List<SysWatermark> sysWatermarks = sysWatermarkMapper.selectByExample(example);
        if (CollectionUtils.isEmpty(sysWatermarks))
            throw new BaseAppException(WatermarkCodeEnum.ERROR_TEMPLATE_CODE.getValue());
        logger.info("查詢得到的水印個數{}", sysWatermarks.size());
        File srcFile = new File(srcImagePath);
        Image srcImage = ImageIO.read(srcFile);
        //創建畫板
        BufferedImage bufferedImage = new BufferedImage(srcImage.getWidth(null), srcImage.getHeight(null), BufferedImage.TYPE_INT_RGB);
        //創建畫筆
        Graphics2D graphics = bufferedImage.createGraphics();
        graphics.drawImage(srcImage, 0, 0, srcImage.getWidth(null), srcImage.getHeight(null), null);
        //添加水印
        Map<String, Double> coordinate;
        logger.info("開始繪製水印,水印個數{}", sysWatermarks.size());
        for (SysWatermark temp : sysWatermarks) {
            //水印類型(0:圖片水印;1文字水印)
            if (!temp.getWatermarkType()) {
                File watermarkFile = new File(imgPrefix + temp.getWatermarkUrl());
                Image watermarkImage = ImageIO.read(watermarkFile);
                ImageIcon imageIcon = new ImageIcon(watermarkImage);
                Image watermarkIconImage = imageIcon.getImage();
                //填充屬性
                logger.info("開始填充圖片水印屬性值");
                //透明度(注意此處如果事int類型,需要轉成float類型,否則你會發現計算結果一直是0,導致顯示不出來你的水印!!!!)
                float transparency = (float) temp.getWatermarkTransparency() / 100;
                graphics.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, transparency));
                coordinate = changeStringToMap(temp.getWatermarkCoordinate());
                graphics.drawImage(watermarkIconImage,
                        (int) (coordinate.get("width") / 100 * srcImage.getWidth(null)),
                        (int) (coordinate.get("height") / 100 * srcImage.getHeight(null)), null);
                continue;
            }
            //將16進制的顏色轉化爲rgb
            Color fontColor = new Color(Integer.valueOf(temp.getWatermarkFontColor().substring(1), 16));
            Font font = new Font(temp.getWatermarkFontType(), Font.PLAIN, temp.getWatermarkSize());
            FontDesignMetrics metrics = FontDesignMetrics.getMetrics(font);
            //繪製矩形
            coordinate = changeStringToMap(temp.getWatermarkCoordinate());
            //設置填充矩形背景顏色:(需要先畫一個空心的矩形,然後再畫一個實心的矩形就可以實現透明度,否則沒有辦法達到效果)
            graphics.setColor(new Color(Integer.valueOf(temp.getWatermarkFontBackgroundColor().substring(1), 16)));
            graphics.drawRect(
                    (int) ((coordinate.get("width") / 100) * srcImage.getWidth(null)),
                    (int) ((coordinate.get("height") / 100) * srcImage.getHeight(null)),
                    metrics.stringWidth(temp.getWatermarkFontContent()), metrics.getHeight());
            //設置矩形的透明度
            graphics.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, ((float) temp.getWatermarkTransparency() / 100)));
            graphics.fillRect(
                    (int) ((coordinate.get("width") / 100) * srcImage.getWidth(null))
                    , (int) ((coordinate.get("height") / 100) * srcImage.getHeight(null))
                    , metrics.stringWidth(temp.getWatermarkFontContent()), metrics.getHeight());
            //設置字體
            graphics.setColor(fontColor);
            graphics.setFont(font);
            graphics.drawString(temp.getWatermarkFontContent(),
                    (int) ((coordinate.get("width") / 100) * srcImage.getWidth(null)),
                    (int) ((coordinate.get("height") / 100) * srcImage.getHeight(null)) + metrics.getAscent());
        }
        logger.info("繪製水印結束");
        graphics.dispose();
        //本地測試開始
        OutputStream out = new FileOutputStream(new File("D:/test.jpg"));
        ImageIO.write(bufferedImage, fileSuffix, out);
        //本地測試結束(如果是本地測試下面的不需要)
        ByteArrayOutputStream os = new ByteArrayOutputStream();
        ImageIO.write(bufferedImage, fileSuffix, os);
        return new ByteArrayInputStream(os.toByteArray());
    }

    /**
     * @param string 圖片定位
     * @return [keys: width , height]
     */
    private static Map<String, Double> changeStringToMap(String string) {
        Map<String, Double> map = new HashMap<>();
        JSONObject object = JSONObject.parseObject(string);
        map.put("width", (double) (int) object.get("width"));
        map.put("height", (double) (int) object.get("height"));
        return map;
    }

}

測試類 :

@RunWith(SpringRunner.class)
@SpringBootTest(classes = EpTradeLmsApplication.class)
public class WaterMarkTest {


    @Resource
    private SysWatermarkMapper sysWatermarkMapper;
    
    @Test
    public void test1() throws Exception {
        
        InputStream inputStream = WatermarkUtils.addWatermark("C:\\Users\\admin\\Desktop\\2.JPG",
                "12,13", "C:\\Users\\admin\\Desktop\\", sysWatermarkMapper);
      
    }
 }

在使用這個的時候,, watermarkIds 和 sysWatermarkMapper 這兩個參數可以不需要;這兩個的作用是查詢對應的水印模板,獲取參數,自己根據自己的業務場景更換即可

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章