java基于原生awt实现 在图片上添加文字水印,支持多水印、自动换行和位置定义

简单的工具类,废话不多说,直接上代码

package com.sime.util.watermark;

import util.Common;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileOutputStream;
import java.util.ArrayList;
import java.util.List;

/**
* 給图片添加文字水印
* 
* @author kdb
*
*/
public class WaterMarkUtils {



   /**
    * 标记水印
    * @param srcImgPath
    *            需要添加水印的图片的路径
    * @param outImgPath
    *            添加水印后图片输出路径
    * @param markContentBeans 需要标记内容列表
    */
   public static  void mark(String srcImgPath, String outImgPath, List<MarkContentModel> markContentBeans) {
       try {
           // 读取原图片信息
           File srcImgFile = new File(srcImgPath);
           Image srcImg = ImageIO.read(srcImgFile);
           int srcImgWidth = srcImg.getWidth(null);
           int srcImgHeight = srcImg.getHeight(null);
           // 加水印
           BufferedImage bufImg = new BufferedImage(srcImgWidth, srcImgHeight, BufferedImage.TYPE_INT_RGB);
           Graphics2D g = bufImg.createGraphics();
           g.drawImage(srcImg, 0, 0, srcImgWidth, srcImgHeight, null);

           for(MarkContentModel contentModel: markContentBeans){
               int fontSize = contentModel.getFontSize();

               Font font = new Font("宋体", Font.PLAIN, fontSize);
               g.setColor(contentModel.getMarkContentColor()); // 根据图片的背景设置水印颜色

               g.setFont(font);


               String  waterMarkContent = contentModel.getContent();

               // 获取其中最长的文字水印的大小


               if(Common.isEmpty(contentModel.getWidth())){
                   contentModel.setWidth(srcImgWidth);
               }

               if(Common.isEmpty(contentModel.getHeight())){
                   contentModel.setWidth(srcImgHeight);
               }

               //绘画区域宽度
               Integer areaWidth = contentModel.getWidth()-80;;
               int fontlen = getWatermarkLength(waterMarkContent, g);




               String  singleChar = null;

               //当大于一行时,循环每个字实现换行输出
               if(fontlen > areaWidth){

                   String[] waterMarkContents = waterMarkContent.split("");

                   // 文字叠加,自动换行叠加,注意符号
                   int tempX = contentModel.getX()+(contentModel.getMargin() /2);
                   int tempY = contentModel.getY()+(contentModel.getMargin() /2);
                   // 单字符长度
                   int tempCharLen = 0;
                   // 单行字符总长度临时计算
                   int tempLineLen = 0;

                   StringBuffer sb = new StringBuffer();
                   for (int i = 0; i < waterMarkContents.length; i++) {
                   //    System.out.println(i+"=="+waterMarkContents[i]);

                        char tempChar = waterMarkContents[i].charAt(0);
                       tempCharLen = getCharLen(tempChar, g);
                       tempLineLen += tempCharLen;

                       // 和图片的长度进行对应的比较操作
                       if (tempLineLen >= areaWidth) {
                           // 长度已经满一行,进行文字叠加
                           g.drawString(sb.toString(), tempX, tempY);
                           System.out.println(sb.toString());
                             // 清空内容,重新追加
                           sb.delete(0, sb.length());
                           tempY += fontSize;
                           tempLineLen = 0;
                       }
                       // 追加字符
                       sb.append(tempChar);

                   }
                   //把最后一行输出出来
                   if(sb.length()>0){
                       g.drawString(sb.toString(), tempX, tempY);
                       System.out.println(sb.toString());
                   }




               }else{
                   g.drawString(contentModel.getContent(), contentModel.getX()+(contentModel.getMargin() /2), contentModel.getY()+(contentModel.getMargin() /2));
               }

           }




           g.dispose();

           // 输出图片
           FileOutputStream outImgStream = new FileOutputStream(outImgPath);
           ImageIO.write(bufImg, "jpg", outImgStream);
           outImgStream.flush();
           outImgStream.close();
       } catch (Exception e) {
           e.printStackTrace();
       }
   }


   public static  int getCharLen(char c, Graphics2D g) {
       return g.getFontMetrics(g.getFont()).charWidth(c);
   }

   /**
    * 获取水印文字总长度
    * 
    * @param waterMarkContent
    *            水印的文字
    * @param g
    * @return 水印文字总长度
    */
   public  static  int getWatermarkLength(String waterMarkContent, Graphics2D g) {
       return g.getFontMetrics(g.getFont()).charsWidth(waterMarkContent.toCharArray(), 0, waterMarkContent.length());
   }


   /**
    * @param args
    */
   public static void main(String[] args) {
       // 原图位置, 输出图片位置, 水印文字颜色, 水印文字
       /*new WaterMarkUtils().mark("/Users/wuqingbin/test/20210002_0.jpg", "/Users/wuqingbin/test/result.jpg",
               Color.red, "圖片來源:XXX");*/



       ArrayList<MarkContentModel> markContentBeans = new ArrayList<>();
       markContentBeans.add(MarkContentModel.builder()
               .content("测测试测试测试测试测试测试测测试测试测试测试测试abcddweweewe测试测试测试测试试测试测试测试测试测试测&&&&&&&&试试测测试试测试测试测------试测试测测试测试测试测测测试测试测试测试测试测试测试测试测试测试测试试123456s")
               .markContentColor(Color.RED)
               .fontSize(30)
               .x(1207)
               .y(191)
               .width(1005)
               .height(947)
               .build()
       );


       markContentBeans.add(MarkContentModel.builder()
               .content("10/36")
               .markContentColor(Color.RED)
               .fontSize(50)
               .x(1207)
               .y(191)
               .width(1005)
               .height(947)
               .position(Position.RIGHT_BOTTOM)
               .build()
       );


      WaterMarkUtils.mark("/Users/xx/test/20210002_0.jpg", "/Users/xx/test/result.jpg",markContentBeans);


    //   System.out.println("sdsdsdsd".split("")[0]);
   }




  

}
import util.Common;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.awt.*;

/**
 * 文字水印数据模型类
 */
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class MarkContentModel {
    //内容
    private String content;
    private Color markContentColor =Color.RED;
    private Integer fontSize =30;
     private Integer margin = 80;
    private Integer x;
    private Integer y;

    //绘画区域的宽和高,如果不传的话,默认使用原图的宽高
    private Integer width;
    private Integer height;

    private Enum position = Position.LEFT_TOP;


    public Integer getX() {
        if(this.position == Position.RIGHT_BOTTOM){
            return this.x+this.getWidth() -400;
        }
        return x;
    }



    public Integer getY() {
        if(this.position == Position.RIGHT_BOTTOM){
            return this.y+this.getHeight() -100;
        }
        return y;
    }

    public Integer getMargin() {
        if(Common.isEmpty(margin)){
            return 80;
        }
        return margin;
    }


}


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值