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 这两个参数可以不需要;这两个的作用是查询对应的水印模板,获取参数,自己根据自己的业务场景更换即可

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