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();
}
}
}
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)