Java实现图片添加水印文字

项目中遇到要在图片上添加水印文字,类似于像生日贺卡那种推送,就是有一张底图,然后我们需要动态替换掉上面名字,性别,部门啥的给公司人员推送一个生日祝福,一开始使用富文本和一些html转图片的工具来做,发现效果不佳,许多样式无法识别等等,后来还是决定使用Java自带的Graphics2D来实现,通过坐标来控制位置,但是颜色和字体那些可能没有前端那么丰富,简单分享一下吧。

水印实体

/**
 * 水印辅助类
 */
@Data
public class WatermarkAssist {
    /**
     * 参数key
     */
    private String paramKey;

    /**
     * 参数value
     */
    private String paramValue;

    /**
     * 字体字体类型
     */
    private String fontType;

    /**
     * 字体字体风格
     */
    private String fontStyle;

    /**
     * 字体大小
     */
    private String fontSize;

    /**
     * 字体颜色
     */
    private String fontColor;

    /**
     * 字体横坐标
     */
    private String fontAbscissa;

    /**
     * 字体纵坐标
     */
    private String fontOrdinate;

}

水印批量处理实体

@Data
public class WatermarkAssistBatch {

    /**
     * 水印集合
     */
    private List<WatermarkAssist> watermarkAssists;

    /**
     * 原图片路径
     */
    private String imagePath;

    /**
     * 生成图片输出位置
     */
    private String imageOutPath;

}

水印生成工具类

public class MyDraw {

    public static void main(String[] args) throws IOException {
        List<WatermarkAssist> watermarkAssists = new ArrayList<>();

        WatermarkAssist watermark1 = new WatermarkAssist();
        watermark1.setFontColor("red");
        watermark1.setFontSize("36");
        watermark1.setFontStyle("PLAIN");
        watermark1.setFontType("MingLiU");
        watermark1.setFontAbscissa("118");
        watermark1.setFontOrdinate("161");
        watermark1.setParamValue("张三");

        WatermarkAssist watermark2 = new WatermarkAssist();
        watermark2.setFontColor("cyan");
        watermark2.setFontSize("22");
        watermark2.setFontStyle("PLAIN");
        watermark2.setFontType("NSimSun");
        watermark2.setFontAbscissa("118");
        watermark2.setFontOrdinate("331");
        watermark2.setParamValue("香港洪兴");

        WatermarkAssist watermark3 = new WatermarkAssist();
        watermark3.setFontColor("green");
        watermark3.setFontSize("12");
        watermark3.setFontStyle("PLAIN");
        watermark3.setFontType("FangSong_GB2312");
        watermark3.setFontAbscissa("124");
        watermark3.setFontOrdinate("383");
        watermark3.setParamValue("男");

        watermarkAssists.add(watermark1);
        watermarkAssists.add(watermark2);
        watermarkAssists.add(watermark3);

        WatermarkAssistBatch batch = new WatermarkAssistBatch();
        batch.setWatermarkAssists(watermarkAssists);
        batch.setImagePath("C:\\Users\\Administrator\\Desktop\\生日推送.jpg");
        batch.setImageOutPath("C:\\Users\\Administrator\\Desktop\\新推送.jpg");

        String s = new MyDraw().addWaterMark(batch);
        System.out.println(s);

    }

    /**
     * 生成水印
     * @param batch
     */
    public String addWaterMark(WatermarkAssistBatch batch) throws IOException {

        if (StringUtils.isBlank(batch.getImagePath())){
            throw new RuntimeException("获取不到图片的位置!");
        }
        
        //项目中是将图片转base64再返回,这里演示就不转base64了
        String base64String= null;

        if (batch.getWatermarkAssists() != null && batch.getWatermarkAssists().size() > 0){
            // 读取原图片信息,得到文件
            File srcImgFile = new File(batch.getImagePath());
            //文件转化为图片
            Image srcImg = ImageIO.read(srcImgFile);
            //获取图片的宽
            int srcImgWidth = srcImg.getWidth(null);
            //获取图片的高
            int srcImgHeight = srcImg.getHeight(null);
            System.out.println("图片的宽度是=" + srcImgWidth + ";  图片的高度是=" + srcImgHeight);
            // 加水印
            BufferedImage bufImg = new BufferedImage(srcImgWidth, srcImgHeight, BufferedImage.TYPE_INT_RGB);
            Graphics2D g = bufImg.createGraphics();
            g.drawImage(srcImg, 0, 0, srcImgWidth, srcImgHeight, null);

            for (WatermarkAssist watermark:batch.getWatermarkAssists()){
                g.setColor(matchColor(watermark.getFontColor()));
                g.setFont(matchFont(watermark.getFontType(), watermark.getFontStyle(), watermark.getFontSize()));
                //画出水印
                g.drawString(watermark.getParamValue()
                        , transformDataType(watermark.getFontAbscissa())
                        , transformDataType(watermark.getFontOrdinate()) + transformDataType(watermark.getFontSize()));
            }

            g.dispose();
            // 输出图片
            FileOutputStream outImgStream = new FileOutputStream(batch.getImageOutPath());
            ImageIO.write(bufImg, "jpg", outImgStream);
            System.out.println("添加水印完成");
            outImgStream.flush();
            outImgStream.close();
        }else{
            throw new RuntimeException("文字信息缺失!");
        }

        return base64String;
    }

    /**
     * 颜色匹配
     * @param fontColor 字体颜色
     * @return 返回颜色对象
     */
    private Color matchColor(String fontColor){
        Color color = null;
        switch (fontColor){
            case "red" :
                color = Color.red;
                break;
            case "white" :
                color = Color.white;
                break;
            case "lightGray" :
                color = Color.lightGray;
                break;
            case "gray" :
                color = Color.gray;
                break;
            case "darkGray" :
                color = Color.darkGray;
                break;
            case "pink" :
                color = Color.pink;
                break;
            case "orange" :
                color = Color.orange;
                break;
            case "yellow" :
                color = Color.yellow;
                break;
            case "green" :
                color = Color.green;
                break;
            case "magenta" :
                color = Color.magenta;
                break;
            case "cyan" :
                color = Color.cyan;
                break;
            case "blue" :
                color = Color.blue;
                break;
            default:
                color = Color.black;
        }
        return color;
    }

    /**
     * 匹配字体
     * @param familyName 字体类型,例如宋体、仿宋等;
     * @param fontStyle 字体风格,例如斜体字、加粗等;
     * @param fontSize 字体大小;
     * @return 返回字体对象
     */
    private Font matchFont(String familyName,String fontStyle,String fontSize){
        int style = 0;
        switch (fontStyle){
            case "PLAIN" :
                //普通
                style = Font.PLAIN;
                break;
            case "BOLD" :
                //加粗
                style = Font.BOLD;
                break;
            case "ITALIC" :
                //斜体
                style = Font.ITALIC;
                break;
            default:
                //粗斜体
                style = Font.BOLD+ Font.ITALIC;
        }
        return new Font(familyName, style, Integer.parseInt(fontSize));
    }

    /**
     * 转换字体的宽高
     * @param fontData 字体数据
     * @return 返回int类型
     */
    private int transformDataType(String fontData){
        return new Double(Double.parseDouble(fontData)).intValue();
    }

}

颜色这边若要根据取色器来制作字体颜色的话,可以获取取色器传过来的16进制码来转成color对象,贴出工具类

@Slf4j
public class ColorUtil {

    /**
     * 16进制码转Color对象
     * @param str
     * @return
     */
    public static Color fromStrToARGB(String str) {
        if (str.length() == 7 && StringUtils.startsWith(str, "#")){
            str = str.replace("#", "FF");
        }
        String str1 = str.substring(0, 2);
        String str2 = str.substring(2, 4);
        String str3 = str.substring(4, 6);
        String str4 = str.substring(6, 8);
        int alpha = Integer.parseInt(str1, 16);
        int red = Integer.parseInt(str2, 16);
        int green = Integer.parseInt(str3, 16);
        int blue = Integer.parseInt(str4, 16);
        Color color = new Color(red, green, blue, alpha);
        return color;
    }

    /**
     * Color对象转16进制码
     * @param color
     * @return
     */
    public static String colorToHexValue(Color color) {
        return intToHexValue(color.getAlpha()) + intToHexValue(color.getRed()) + intToHexValue(color.getGreen()) + intToHexValue(color.getBlue());
    }

    public static String intToHexValue(int number) {
        String result = Integer.toHexString(number & 0xff);
        while (result.length() < 2) {
            result = "0" + result;
        }
        return result.toUpperCase();
    }

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值