pdf和图片java代码生成水印

水印会随着水印文本的长度而自动是修改字体大小,使其可以合理的放置于一行。
效果图如下:
在这里插入图片描述

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;

import javax.imageio.ImageIO;
import javax.swing.JLabel;
import java.awt.FontMetrics;
import java.awt.Color;
import java.awt.AlphaComposite;
import java.awt.Font;
import java.awt.RenderingHints;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;

import com.itextpdf.text.*;
import com.itextpdf.text.pdf.BaseFont;
import com.itextpdf.text.pdf.PdfContentByte;
import com.itextpdf.text.pdf.PdfGState;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.PdfStamper;
import com.redxun.common.exception.asserts.BizAssertTips;

import lombok.extern.slf4j.Slf4j;


@Slf4j
public class WaterMarkUtil {

    //为了使文字向左移动5像素
	private static int interval = -5;
	
	/**
	 * PDF加文字水印
	 * @param inputFile        PDF文件输入路径
	 * @param outputFile       PDF文件输出路径
	 * @param waterMarkName    自定义水印
	 * @throws Exception 
	 */
	public static void waterMarkPdf(InputStream inputFile,OutputStream outputFile, String waterMarkName) throws Exception {

		//根据水印文字长度,更改水印文字大小
		int size = 0;
		if (waterMarkName.length() <= 13) {
			size = 30;
		}else if(waterMarkName.length() > 13 && waterMarkName.length() <= 33) {
			size = 25;
		} else {
			//通过文字长度自动调节字体大小
			size = 800/waterMarkName.length()-1;
		}
		PdfStamper stamper = null;
		PdfReader reader = null;
		try {	
			reader = new PdfReader(inputFile);
			
			stamper = new PdfStamper(reader, outputFile);
			//设置文字样式
			BaseFont base = BaseFont.createFont("STSong-Light","UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
			
			Rectangle pageRect = null;
			
			PdfGState gs = new PdfGState();
			//设置透明度
			gs.setFillOpacity(0.2f);
			
			gs.setStrokeOpacity(0.4f);
			
			int total = reader.getNumberOfPages() + 1;
			
			JLabel label = new JLabel();
			
			FontMetrics metrics;
			
			int textH = 0;
			
			int textW = 0;
			//设置自定义水印
			label.setText(waterMarkName);
			
			metrics = label.getFontMetrics(label.getFont());
			
			textH = metrics.getHeight();
			
			textW = metrics.stringWidth(label.getText());
			
			PdfContentByte under = null;
		
			for (int i = 1; i < total; i++) {
		
				pageRect = reader.getPageSizeWithRotation(i);
				
				under = stamper.getOverContent(i);
				
				under.saveState();
				
				under.setGState(gs);
				
				under.beginText();
				
				under.setFontAndSize(base, size);
		
				//调整for循环的宽高可更改水印位置,高:textH 宽:textW
				for (int height = interval + textH; height < pageRect.getHeight(); height = height + textH*10) {
		
					for (int width = interval + textW; width < pageRect.getWidth() + textW; width = width + textW*5) {
				        //水印文字成21度角倾斜
						//这里居中  故设置x为中线。
						under.showTextAligned(Element.ALIGN_CENTER, waterMarkName, pageRect.getWidth()/2 , height - textH, 21);			
					}	
				}
				// 添加水印文字
				under.endText();
			}
			} catch (Exception e) {
				e.printStackTrace();
				throw e;
			} finally {
				//关闭流
				if(stamper != null) {
				   stamper.close();
				} 
				if(reader != null) {
				   reader.close();
				}
			} 
	}
	
	
	public static void main(String[] args) throws Exception {
		
		
		FileInputStream in = new FileInputStream("C:\\Users\\hxd\\Desktop\\xxx_20230111151716.jpg");
		FileOutputStream out = new FileOutputStream("C:\\Users\\hxd\\Desktop\\xxx_20230111151716-1.jpg");
		clearImage(in, out, "这是一个测试水印这是一个测试水印这是一个");
	}
	/**
	 * 图片构建水印的时候高度间隔
	 */
	static final int hight_interval=220;
    /**
	 * 图片加文字水印
	 * @param text            水印内容
	 * @param transparency    清晰度
     * @param imageName       图片名(含后缀)
     * @param path            图片保存位置
	 */
	public static void clearImage(InputStream inputFile,OutputStream outputFile, String waterMarkName) {
		try {
	        // 读取本地图片文件
	         
 
	        // 将文件对象转化为图片对象(限png、jpg、gif)
	         BufferedImage image = ImageIO.read(inputFile);
                //设置水印字体大小
		        int size = 5;
		        if (image.getWidth() >= waterMarkName.length() * 30) {
		        	size = 30;
				}else if (image.getWidth() >= waterMarkName.length() * 20) {
					size = 20;
				}else if (image.getWidth() >= waterMarkName.length() * 10) {
					size = 10;
				} else {
					size = image.getWidth()/waterMarkName.length()+1;
				}
	
		        Graphics2D pen = image.createGraphics();
	
		        pen.setColor(Color.BLACK);
		        // 设置画笔字体样式为微软雅黑 斜体:Font.ITALIC
		        pen.setFont(new Font("微软雅黑", Font.BOLD, size));
		        //文字倾斜
		        //double shx, double shy  
		        //0表示x轴的旋转 y表示y轴旋转,我们不希望x轴有旋转。故设置为0.如果需要y的倾斜度陡峭或者平缓,改第二个参数shy
		        pen.shear(0, -0.32);
		        //消除文字锯齿
		        pen.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
		        //设置文字透明度
		        pen.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, 0.3F));
		        //获取文本长度,用来设置坐标
		        int len = waterMarkName.length();
		        //获取水印坐标位置
		        int width = image.getWidth()/2;
		       
		        if (image.getWidth() - (len*size) > 0) {
		        	//根据水印字体长度,控制水印位置
					width = image.getWidth()/2 - (len/2)*size;
				} else {
					width=1;
				}
		        int imgH = image.getHeight();
		        if(imgH /2 < hight_interval) {
		           //添加水印   从最中间开始加水印
		           pen.drawString(waterMarkName, width, imgH/2);
		        } else {
		        	for (int h = 10; h < imgH; h+=hight_interval) {
		        		
		        		 pen.drawString(waterMarkName, width, h);
					}
		        }
                //此处需设置图片类型
				ImageIO.write(image, "png", outputFile);
				outputFile.close();
			
		} catch (Exception e) {
			e.printStackTrace();
			BizAssertTips.fail("生成图片水印失败");
		}
    }
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值