Java生成文字水印

工具类

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.font.TextAttribute;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.OutputStream;
import java.text.AttributedCharacterIterator;
import java.text.AttributedString;

/**
 * Java生成水印文字(可以改造成生成图片的水印文字,生成图片的水印图片)
 * Created by wesley on 2017-11-02.
 */
public class ImageUtil {

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

    // 宽度
    private static final int WIDTH = 360;
    // 高度
    private static final int HEIGHT = 140;
    // 水印透明度
    private static float alpha = 1.0f;
    // 水印横向位置
    private static int positionWidth = 80;
    // 水印纵向位置
    private static int positionHeight = 30;
    // 水印文字字体
    private static Font font = new Font("PingFang SC Regular", Font.PLAIN, 44);
    // 水印文字颜色
    private static Color color = new Color(230, 230, 230);

    /**
     * 创建背景白色的单水印图片
     * @param os
     * @param text
     * @throws IOException
     */
    public static void createSingleWaterMarkImage(OutputStream os, String text) throws IOException {
        GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
        String script[] = ge.getAvailableFontFamilyNames();
        for(String s:script){
            logger.info("字体有:{}",s);
        }
        // 1.创建空白图片
        BufferedImage image = new BufferedImage(
                WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB);
        // 2.获取图片画笔
        Graphics2D g = image.createGraphics();
        // 3.设置画笔颜色
        g.setColor(Color.white);
        // 4.绘制矩形背景
        g.fillRect(0, 0, WIDTH, HEIGHT);
        // 5.绘制矩形边框
        g.setColor(Color.lightGray);
        g.drawRect(0, 0, WIDTH - 10, HEIGHT - 10);
        // 添加水印文字
        // 6、处理文字
        AttributedString ats = new AttributedString(text);
        ats.addAttribute(TextAttribute.FONT, font, 0, text.length());
        AttributedCharacterIterator iter = ats.getIterator();
        // 7、设置对线段的锯齿状边缘处理
        g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
        g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        // 8、设置水印旋转
        g.rotate(Math.toRadians(-15), (double) image.getWidth() / 2, (double) image.getHeight() / 2);
        // 9、设置水印文字颜色
        g.setColor(color);
        // 10、设置水印文字Font
        g.setFont(font);
        // 11、设置水印文字透明度
        g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, alpha));
        g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER));
        // 12、水印位置
        g.drawString(iter, positionHeight, positionWidth);
        // 13、释放资源
        g.dispose();
        ImageIO.write(image, "JPG", os);
        logger.info("打印水印成功...");
    }

    /**
     * 创建多水印图片
     * @param os
     * @param text
     * @throws IOException
     */
    public static void createMoreWaterMarkImage(OutputStream os, String text) throws IOException {
        GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
        String script[] = ge.getAvailableFontFamilyNames();
        for(String s:script){
            logger.info("字体有:{}",s);
        }
        // 1.创建空白图片
        BufferedImage image = new BufferedImage(
                WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB);
        // 2.获取图片画笔
        Graphics2D g = image.createGraphics();
        // 3.设置画笔颜色
        g.setColor(Color.white);
        // 4.绘制矩形背景
        g.fillRect(0, 0, WIDTH, HEIGHT);
        // 5.绘制矩形边框
        g.setColor(Color.lightGray);
        g.drawRect(0, 0, WIDTH - 10, HEIGHT - 10);
        // 添加水印文字
        // 6、设置对线段的锯齿状边缘处理
        g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
        g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        // 7、设置水印旋转
        g.rotate(Math.toRadians(-15), (double) image.getWidth() / 2, (double) image.getHeight() / 2);
        // 8、设置水印文字颜色
        g.setColor(color);
        // 9、设置水印文字Font
        g.setFont(font);
        // 10、设置水印文字透明度
        g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, alpha));
        g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER));
        // 11、水印位置
        // 计算水印位置方法一
        for (int height = -WIDTH/2 ; height < 1.5*HEIGHT; height = height +  2*font.getSize()) {
            for (int weight = -HEIGHT/2 ; weight < 1.5*WIDTH; weight = weight + 25*getTextLength(text)) {
                g.drawString(text, weight, height);
            }
        }
//        计算水印位置方式二
//        int x = -WIDTH/2;
//        int y = -HEIGHT/2;
//        while(x<WIDTH*1.5){
//            y = -HEIGHT/2;
//            while(y<HEIGHT*1.5){
//                //添加水印效果 第一参数->设置的内容,后面两个参数->文字在图片上的坐标位置(x,y)
//                g.drawString(text, x, y);//y保证至少可以显示一个水印的高度
//                y +=font.getSize()+50;//100为间隔值,即每个水印之间的间隔
//            }
//            x +=font.getSize()*getTextLength(text)+50;
//        }
        // 12、释放资源
        g.dispose();
        ImageIO.write(image, "JPG", os);
        logger.info("打印水印成功...");
    }

    //获取文本长度
    public 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) {//字节长度大于1,说明是中文,那么需要延长文本长度
                length++;
            }
        }
        //计算总共有多少个字节,也就是有多少个字
        length = (length % 2 == 0) ? length / 2 : length / 2 + 1;
        return length;
    }

    /**
     * 创建背景透明图片
     *
     * @param os
     * @param text
     * @throws IOException
     */
    public static void createTransparentImage(OutputStream os, String text) throws IOException {
        // 创建空白图片
        BufferedImage image = new BufferedImage(
                WIDTH, HEIGHT, BufferedImage.TYPE_INT_ARGB);
        // 获取图片画笔
        Graphics2D g = image.createGraphics();
        // 设置背景透明度
        image = g.getDeviceConfiguration().createCompatibleImage(WIDTH, HEIGHT, Transparency.TRANSLUCENT);
        g.dispose();
        g = image.createGraphics();
        // 设置对线段的锯齿状边缘处理
        // g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
        g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        // 文字处理
        AttributedString ats = new AttributedString(text);
        ats.addAttribute(TextAttribute.FONT, font, 0, text.length());
        AttributedCharacterIterator iter = ats.getIterator();
        // 水印旋转
        g.rotate(Math.toRadians(-15), (double) image.getWidth() / 2, (double) image.getHeight() / 2);
        // 设置水印文字颜色
        g.setColor(color);
        // 设置水印文字Font
        g.setFont(font);
        // 设置水印文字透明度
         g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, alpha));
        // 设置水印文字透明度结束
         g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER));
        // 水印位置
        g.drawString(iter, positionHeight, positionWidth);
        // 释放资源
        g.dispose();
        ImageIO.write(image, "PNG", os);
    }

}

controller中使用:

/**
   * 生成文字水印图片
   *
   * @param response
   * @param staffNo
   */
  @RequestMapping("/getImage/")
  public void getImage(HttpServletResponse response) {
      response.setContentType("image/*");
      try {
          OutputStream os = response.getOutputStream();
          String text = “测试水印文字图片”;
          logger.info("需要打印的水印文字:{}",text);
          ImageUtil.createTransparentImage(os, text);
      } catch (IOException e) {
          logger.error("打印水印异常...");
      }

  }

效果图: 输入图片说明

转载于:https://my.oschina.net/zhengweishan/blog/1559974

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值