Java实现对image图片、pdf文件加水印

Java实现对image图片、pdf文件加水印,第1张

1、图片
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;

public class ImageWatermark {

    // 旋转角度(单位:弧度)
	private static final double ROTATE_ANGLE_RADIANS = Math.toRadians(30);  
	private static final double SIN_ROTATE_ANGLE = Math.sin(ROTATE_ANGLE_RADIANS);
	private static final double COS_ROTATE_ANGLE = Math.cos(ROTATE_ANGLE_RADIANS);

	//定义水印文字样式
	private static final Color FONT_COLOR = new Color(0x70, 0x70, 0x70);
    //宋体  微软雅黑
	private static final String FONT_NAME = "宋体";
	private static final int FONT_STYLE = Font.BOLD;
	private static final float ALPHA = 0.2F;

    public static void main(String[] args) throws IOException {
        ImageWatermark.paintWatermarkImage(inputPath, outPutPath);
    }

    /**
	 * 
	 * @param input 图片原始路径
	 * @param outPutPath 图片加水印之后的路径
	 */
    public static void paintWatermarkImage(String input, String outPutPath) {
		FileOutputStream bos = null;
		String text = "水印内容\n换行符换行";
		Image image = null;
		try {
			image = ImageIO.read(new File(input));
		} catch (IOException e) {
			e.printStackTrace();
		}
		//计算原始图片宽度长度
		int width = image.getWidth(null);
		int height = image.getHeight(null);

		// 三角函数算出来的最小宽高,不浪费内存
		width = (int) (width * COS_ROTATE_ANGLE + height * SIN_ROTATE_ANGLE);
		height = (int) (width * SIN_ROTATE_ANGLE + height * COS_ROTATE_ANGLE);
		BufferedImage bufferedImage =null;
		try {
			//创建图片缓存对象
			bufferedImage= new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
			//创建java绘图工具对象
			Graphics2D g = bufferedImage.createGraphics();
			//参数主要是,原图,坐标,宽高
			g.drawImage(image, 0, 0, width, height, null);
			// 考虑到大尺寸图片,水印在手机上显示比较小,字体大小根据图片宽度来设置
			g.setFont(new Font(FONT_NAME, FONT_STYLE, width / text.length()));
			g.setColor(FONT_COLOR);
			// 设置旋转角度,透明度
			g.rotate(-ROTATE_ANGLE_RADIANS, bufferedImage.getWidth() / 2, bufferedImage.getHeight() / 2);
			g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, ALPHA));

			g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
			List watermarkTextLines = Arrays.asList(text.split("\n"));
			int blockWidth = getTextBlockWidth(g, watermarkTextLines);
			int blockHeight = getTextBlockHeight(g, watermarkTextLines);
			int evenStartX = -(blockWidth + 480) / 2;  // 偶数行的起始位置
			evenStartX = 0;
			int lineNum = 0;  // 当前行号
			for (int y = 20; y < height; y += (blockHeight*3+ blockHeight)) {
				// 水印交错排列
				lineNum++;
				int startX = lineNum % 2 == 0 ? evenStartX : 0;

				for (int x = startX; x < width; x += (blockWidth*3+ blockWidth)) {
					drawString(g, blockWidth, x, y, watermarkTextLines);
				}
			}
			g.dispose();
			bos = new FileOutputStream(new File(outPutPath));
			String suffix = input.substring(input.lastIndexOf(".") + 1);
			ImageIO.write(bufferedImage, suffix, bos);
		} catch (IOException e) {
			e.printStackTrace();
		}finally {
			if (bufferedImage != null) {
				bufferedImage.getGraphics().dispose();
			}
            if (bos != null) {
                try {
                    bos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
		}
	}


	private static int getTextBlockHeight(Graphics g, List watermarkTextLines) {
		return g.getFontMetrics().getHeight() * watermarkTextLines.size();
	}

	private static int getTextBlockWidth(Graphics g, List watermarkTextLines) {
		int blockWidth = 0;  // 整个文本块的宽度
		for (String line : watermarkTextLines) {
			int lineWidth = g.getFontMetrics().stringWidth(line);
			if (lineWidth > blockWidth) {
				blockWidth = lineWidth;
			}
		}
		return blockWidth;
	}

	// 绘制一个水印块,多行文本居中对齐
	private static void drawString(Graphics g, int blockWidth, int x, int y, List watermarkTextLines) {
		int midX = x + blockWidth / 2;  // 中线的x坐标
		for (String line : watermarkTextLines) {
			int lineWidth = g.getFontMetrics().stringWidth(line);
			int lineX = midX - lineWidth / 2;
			// 对齐
			lineX = lineX - (int) Math.round(y * SIN_ROTATE_ANGLE / COS_ROTATE_ANGLE);
			g.drawString(line, lineX, y);
			y += g.getFontMetrics().getHeight();
		}
	}


}

2、pdf
  
        
            com.itextpdf
            itextpdf
            5.5.10
        
        
            com.itextpdf
            itext-asian
            5.2.0
        

import com.alibaba.fastjson.JSONObject;
import com.itextpdf.text.BaseColor;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Element;
import com.itextpdf.text.Rectangle;
import com.itextpdf.text.pdf.*;
import lombok.extern.slf4j.Slf4j;

import javax.swing.*;
import java.awt.*;
import java.io.*;
import java.util.UUID;

@Slf4j
public class WaterMarkUtil {

	private static final String MARK_TEXT = "水印内容||换行符换行";
	private static final BaseColor bg = new BaseColor(0x70, 0x70, 0x70);
	private static final int FONT_SIZE = 20;
	private static final float ALPHA = 0.2F;
    
	public static void main(String[] args) throws IOException, DocumentException {
		String input = "http://域名//sdec-data//2021/09//b9fea623-28cf-421d-8066-63eafc1405ce.pdf";
		String output = "D:\2020\" + UUID.randomUUID() + ".pdf";
		setWatermark(output, input);
	}


	/**
	 * 
	 * @param output pdf文件加水印后生成的路径
	 * @param input  pdf文件原路径
	 * @throws DocumentException
	 * @throws IOException
	 */
    	public static void setWatermark(String output, String input)
			throws DocumentException, IOException {

		// 使用"||"将内容进行分割
		String[] waterMarkContents = MARK_TEXT.split("\|\|");
		log.info("水印内容:{}", JSONObject.toJSONString(waterMarkContents));
		/*File inputFile = new File(input);
		int inputDot = inputFile.getName().lastIndexOf('.');
		String inputPath = inputFile.getParent() + File.separator + inputFile.getName().substring(0,
				inputDot) + ".pdf";*/
		PdfReader reader = new PdfReader(input);
		File file = new File(output);
		int dot = file.getName().lastIndexOf('.');
		String pdfPath = file.getParent() + File.separator + file.getName().substring(0, dot) + ".pdf";
		log.info("水印:{}", pdfPath);
		FileOutputStream fileOutputStream = new FileOutputStream(new File(pdfPath));

		PdfStamper stamper = new PdfStamper(reader,
				new BufferedOutputStream(fileOutputStream));

		// 获取总页数 +1, 下面从1开始遍历
		int total = reader.getNumberOfPages() + 1;

       //需下载simsun.ttc字体
        //下载地址:http://a.xzfile.com//down3/simsun_downcc.com.zip
		BaseFont base = BaseFont.createFont("/simsun.ttc,0", BaseFont.IDENTITY_H,
				BaseFont.EMBEDDED);

		// 间隔
		int interval = 20;
		// 获取水印文字的最大高度和宽度
		int textH = 0, textW = 0;
		for (int j = 0; j < waterMarkContents.length; j++) {
			JLabel label = new JLabel();
			log.info("waterMarkContents[j]:{}", waterMarkContents[j]);
			label.setText(waterMarkContents[j]);
			FontMetrics metrics = label.getFontMetrics(label.getFont());
			if (textH < metrics.getHeight()) {
				textH = metrics.getHeight();
			}
			if (textW < metrics.stringWidth(label.getText())) {
				textW = metrics.stringWidth(label.getText());
			}


			// 设置水印透明度
			PdfGState gs = new PdfGState();
			gs.setFillOpacity(ALPHA);
			gs.setStrokeOpacity(ALPHA);

			Rectangle pageSizeWithRotation = null;
			PdfContentByte content = null;
			for (int i = 1; i < total; i++) {
				content = stamper.getOverContent(i);
				content.saveState();
				content.setGState(gs);

				// 设置字体和字体大小
				content.beginText();
					content.setFontAndSize(base, FONT_SIZE);

				// 设置颜色
				content.setColorFill(bg);

				// 获取每一页的高度、宽度
				pageSizeWithRotation = reader.getPageSizeWithRotation(i);
				float pageHeight = (float) pageSizeWithRotation.getHeight();
				float pageWidth = (float) pageSizeWithRotation.getWidth();

				// 根据纸张大小多次添加, 水印文字成45度角倾斜
				for (int height = interval + textH; height < pageHeight; height = height + textH * 6) {
					for (int width = interval + textW; width < pageWidth + textW; width = width + textW * 2) {
						// 将分段的字段进行输出编写
						for (int z = 0; z < waterMarkContents.length; z++) {
							content.showTextAligned(Element.ALIGN_RIGHT, waterMarkContents[z], width - textW,
									height - (textH + 10) * (z + 1), -45);
						}
					}
				}

				content.endText();
			}

			// 关闭流
			stamper.close();
			reader.close();
		}
	}

}

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/langs/719624.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-04-25
下一篇 2022-04-25

发表评论

登录后才能评论

评论列表(0条)

保存