转:https://www.cnblogs.com/qlqwjy/p/9326468.html

    ——————————————图片水印——————————————
    1.添加文字水印

    复制代码
    import java.awt.Color;
    import java.awt.Font;
    import java.awt.Graphics2D;
    import java.awt.Image;
    import java.awt.image.BufferedImage;
    import java.io.File;
    import java.io.FileOutputStream;

    import javax.imageio.ImageIO;

    /
    給图片添加文字水印

    @author liqiang

    */
    public class WaterMarkUtils {

    /

    @param args
    /
    public static void main(String[] args) {
    // 原图位置, 输出图片位置, 水印文字颜色, 水印文字
    new WaterMarkUtils().mark(“C:/Users/liqiang/Desktop/图片/kdmt.jpg”, “C:/Users/liqiang/Desktop/图片/kdmt1.jpg”,
    Color.red, “圖片來源:XXX”);
    }

    /
    图片添加水印

    @param srcImgPath
    需要添加水印的图片的路径
    @param outImgPath
    添加水印后图片输出路径
    @param markContentColor
    水印文字的颜色
    @param waterMarkContent
    水印的文字
    */
    public void mark(String srcImgPath, String outImgPath, Color markContentColor, String waterMarkContent) {
    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);
    // Font font = new Font(“Courier New”, Font.PLAIN, 12);
    Font font = new Font(“宋体”, Font.PLAIN, 20);
    g.setColor(markContentColor); // 根据图片的背景设置水印颜色

    g.setFont(font);
    int x = srcImgWidth - getWatermarkLength(waterMarkContent, g) - 3;
    int y = srcImgHeight - 3;
    // int x = (srcImgWidth - getWatermarkLength(watermarkStr, g)) / 2;
    // int y = srcImgHeight / 2;
    g.drawString(waterMarkContent, x, y);
    g.dispose();
    // 输出图片
    FileOutputStream outImgStream = new FileOutputStream(outImgPath);
    ImageIO.write(bufImg, “jpg”, outImgStream);
    outImgStream.flush();
    outImgStream.close();
    } catch (Exception e) {
    e.printStackTrace();
    }
    }

    /

    获取水印文字总长度

    @param waterMarkContent
    水印的文字
    @param g
    @return 水印文字总长度
    /
    public int getWatermarkLength(String waterMarkContent, Graphics2D g) {
    return g.getFontMetrics(g.getFont()).charsWidth(waterMarkContent.toCharArray(), 0, waterMarkContent.length());
    }
    }
    复制代码
    结果:







    2.给图片添加图片水印

    复制代码
    import java.awt.AlphaComposite;
    import java.awt.Graphics2D;
    import java.awt.Image;
    import java.awt.RenderingHints;
    import java.awt.image.BufferedImage;
    import java.io.File;
    import java.io.FileOutputStream;
    import java.io.OutputStream;

    import javax.imageio.ImageIO;
    import javax.swing.ImageIcon;

    /**
    給图片添加图片

    @author liqiang

    /
    public class WaterMarkUtils {

    /
    @param args
    /
    public static void main(String[] args) {
    String srcImgPath = “C:/Users/liqiang/Desktop/图片/kdmt.jpg”;
    String iconPath = “C:/Users/liqiang/Desktop/图片/qlq.jpeg”;
    String targerPath = “C:/Users/liqiang/Desktop/图片/qlq1.jpeg”;
    String targerPath2 = “C:/Users/liqiang/Desktop/图片/qlq2.jpeg”;
    // 给图片添加水印
    WaterMarkUtils.markImageByIcon(iconPath, srcImgPath, targerPath);
    // 给图片添加水印,水印旋转-45
    WaterMarkUtils.markImageByIcon(iconPath, srcImgPath, targerPath2, -45);

    }

    /

    给图片添加水印

    @param iconPath
    水印图片路径
    @param srcImgPath
    源图片路径
    @param targerPath
    目标图片路径
    /
    public static void markImageByIcon(String iconPath, String srcImgPath, String targerPath) {
    markImageByIcon(iconPath, srcImgPath, targerPath, null);
    }

    /**
    给图片添加水印、可设置水印图片旋转角度

    @param iconPath
    水印图片路径
    @param srcImgPath
    源图片路径
    @param targerPath
    目标图片路径
    @param degree
    水印图片旋转角度
    /
    public static void markImageByIcon(String iconPath, String srcImgPath, String targerPath, Integer degree) {
    OutputStream os = null;
    try {
    Image srcImg = ImageIO.read(new File(srcImgPath));

    BufferedImage buffImg = new BufferedImage(srcImg.getWidth(null), srcImg.getHeight(null),
    BufferedImage.TYPE_INT_RGB);

    // 得到画笔对象
    // Graphics g= buffImg.getGraphics();
    Graphics2D g = buffImg.createGraphics();

    // 设置对线段的锯齿状边缘处理
    g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);

    g.drawImage(srcImg.getScaledInstance(srcImg.getWidth(null), srcImg.getHeight(null), Image.SCALE_SMOOTH), 0,
    0, null);

    if (null != degree) {
    // 设置水印旋转
    g.rotate(Math.toRadians(degree), (double) buffImg.getWidth() / 2, (double) buffImg.getHeight() / 2);
    }

    // 水印图象的路径 水印一般为gif或者png的,这样可设置透明度
    ImageIcon imgIcon = new ImageIcon(iconPath);

    // 得到Image对象。
    Image img = imgIcon.getImage();

    float alpha = 0.5f; // 透明度
    g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, alpha));

    // 表示水印图片的位置
    g.drawImage(img, 150, 300, null);

    g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER));

    g.dispose();

    os = new FileOutputStream(targerPath);

    // 生成图片
    ImageIO.write(buffImg, “JPG”, os);

    System.out.println(“图片完成添加Icon印章。。。。。。”);
    } catch (Exception e) {
    e.printStackTrace();
    } finally {
    try {
    if (null != os)
    os.close();
    } catch (Exception e) {
    e.printStackTrace();
    }
    }
    }
    }
    复制代码
    效果:











    ———————————————PDF水印(itext添加水印)——————————————
    在这里就同时给PDF添加文字水印和图片水印(每一页都添加一个文字水印和图片水印)

    依赖的包:

    复制代码


    com.lowagie
    itextasian
    1.0


    com.lowagie
    itext
    2.1.7


    复制代码


    代码:

    复制代码
    import java.awt.Color;
    import java.io.BufferedOutputStream;
    import java.io.File;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.text.SimpleDateFormat;
    import java.util.Calendar;

    import com.lowagie.text.DocumentException;
    import com.lowagie.text.Element;
    import com.lowagie.text.Image;
    import com.lowagie.text.pdf.BaseFont;
    import com.lowagie.text.pdf.PdfContentByte;
    import com.lowagie.text.pdf.PdfGState;
    import com.lowagie.text.pdf.PdfReader;
    import com.lowagie.text.pdf.PdfStamper;

    public class TestWaterPrint {
    public static void main(String[] args) throws DocumentException, IOException {
    // 要输出的pdf文件
    BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(new File(“E:/abc.pdf”)));
    Calendar cal = Calendar.getInstance();
    SimpleDateFormat format = new SimpleDateFormat(“yyyy-MM-dd hh:mm:ss”);
    // 将pdf文件先加水印然后输出
    setWatermark(bos, “G:/1.pdf”, format.format(cal.getTime()) + “ 下载使用人:” + “测试user”, 16);
    }

    /

    @param bos输出文件的位置
    @param input
    原PDF位置
    @param waterMarkName
    页脚添加水印
    @param permission
    权限码
    @throws DocumentException
    @throws IOException
    /
    public static void setWatermark(BufferedOutputStream bos, String input, String waterMarkName, int permission)
    throws DocumentException, IOException {
    PdfReader reader = new PdfReader(input);
    PdfStamper stamper = new PdfStamper(reader, bos);
    int total = reader.getNumberOfPages() + 1;
    PdfContentByte content;
    BaseFont base = BaseFont.createFont(“STSong-Light”, “UniGB-UCS2-H”, BaseFont.EMBEDDED);
    PdfGState gs = new PdfGState();
    for (int i = 1; i < total; i++) {
    content = stamper.getOverContent(i);// 在内容上方加水印
    // content = stamper.getUnderContent(i);//在内容下方加水印
    gs.setFillOpacity(0.2f);
    // content.setGState(gs);
    content.beginText();
    content.setColorFill(Color.LIGHT_GRAY);
    content.setFontAndSize(base, 50);
    content.setTextMatrix(70, 200);
    content.showTextAligned(Element.ALIGN_CENTER, “公司内部文件,请注意保密!”, 300, 350, 55);
    Image image = Image.getInstance(“G:/2.jpeg”);
    /

    img.setAlignment(Image.LEFT | Image.TEXTWRAP);
    img.setBorder(Image.BOX); img.setBorderWidth(10);
    img.setBorderColor(BaseColor.WHITE); img.scaleToFit(100072);//大小
    img.setRotationDegrees(-30);//旋转
    */
    image.setAbsolutePosition(200, 206); // set the first background
    // image of the absolute
    image.scaleToFit(200, 200);
    content.addImage(image);
    content.setColorFill(Color.BLACK);
    content.setFontAndSize(base, 8);
    content.showTextAligned(Element.ALIGN_CENTER, “下载时间:” + waterMarkName + “”, 300, 10, 0);
    content.endText();

    }
    stamper.close();
    }
    }
    复制代码
    效果:







    补充:关于字体的用法

    1.使用iTextAsian.jar中的字体

    BaseFont.createFont(“STSong-Light”, “UniGB-UCS2-H”,BaseFont.NOT_EMBEDDED);



    2.使用Windows系统字体

    BaseFont.createFont(“C:/WINDOWS/Fonts/SIMYOU.TTF”, BaseFont.IDENTITY_H,BaseFont.NOT_EMBEDDED);



    3.使用资源字体(ClassPath) ,也就是将ttf字体拷贝到src目录

    BaseFont.createFont(“/SIMYOU.TTF”, BaseFont.IDENTITY_H,BaseFont.NOT_EMBEDDED);



      三种方法亲测有效,而且使用itext自带的字体就够用了,可以正确的处理中文。

    补充:关于获取PDF页面高度、宽度然后进行动态定位,比如说根据页面宽度实现平铺水印:

    复制代码
    package cn.xm.exam.test;

    import java.awt.FontMetrics;
    import java.io.BufferedOutputStream;
    import java.io.File;
    import java.io.FileOutputStream;
    import java.io.IOException;

    import javax.swing.JLabel;

    import com.itextpdf.text.DocumentException;
    import com.itextpdf.text.Element;
    import com.itextpdf.text.Rectangle;
    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;

    public class TestWaterPrint {
    public static void main(String[] args) throws DocumentException, IOException {
    // 要输出的pdf文件
    BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(new File(“F:/test1.pdf”)));
    // 将pdf文件先加水印然后输出
    setWatermark(bos, “F:/test.pdf”, “测试user”);
    }

    /


    @param bos输出文件的位置
    @param input
    原PDF位置
    @param waterMarkName
    页脚添加水印
    @throws DocumentException
    @throws IOException
    /
    public static void setWatermark(BufferedOutputStream bos, String input, String waterMarkName)
    throws DocumentException, IOException {

    PdfReader reader = new PdfReader(input);
    PdfStamper stamper = new PdfStamper(reader, bos);

    // 获取总页数 +1, 下面从1开始遍历
    int total = reader.getNumberOfPages() + 1;
    // 使用classpath下面的字体库
    BaseFont base = null;
    try {
    base = BaseFont.createFont(“/calibri.ttf”, BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
    } catch (Exception e) {
    // 日志处理
    e.printStackTrace();
    }

    // 间隔
    int interval = -5;
    // 获取水印文字的高度和宽度
    int textH = 0, textW = 0;
    JLabel label = new JLabel();
    label.setText(waterMarkName);
    FontMetrics metrics = label.getFontMetrics(label.getFont());
    textH = metrics.getHeight();
    textW = metrics.stringWidth(label.getText());
    System.out.println(“textH: “ + textH);
    System.out.println(“textW: “ + textW);

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

    Rectangle pageSizeWithRotation = null;
    PdfContentByte content = null;
    for (int i = 1; i < total; i++) {
    // 在内容上方加水印
    content = stamper.getOverContent(i);
    // 在内容下方加水印
    // content = stamper.getUnderContent(i);
    content.saveState();
    content.setGState(gs);

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

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

    // 根据纸张大小多次添加, 水印文字成30度角倾斜
    for (int height = interval + textH; height < pageHeight; height = height + textH
    3) {
    for (int width = interval + textW; width < pageWidth + textW; width = width + textW 2) {
    content.showTextAligned(Element.ALIGN_LEFT, waterMarkName, width - textW, height - textH, 30);
    }
    }

    content.endText();
    }

    // 关流
    stamper.close();
    reader.close();
    }
    }
    复制代码
    结果:







    补充:关于itext添加倾斜字体的水印

      上面使用的是BaseFont,无法添加样式,Font可以添加样式,但是setFontAndSize方法不接受Font参数。所以只能变通实现:

    例如:在每页右下角生成倾斜水印

    复制代码
    package cn.xm.exam.test;

    import java.io.BufferedOutputStream;
    import java.io.File;
    import java.io.FileOutputStream;
    import java.io.IOException;

    import com.itextpdf.text.DocumentException;
    import com.itextpdf.text.Rectangle;
    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;

    public class TestWaterPrint {
    public static void main(String[] args) throws DocumentException, IOException {
    // 要输出的pdf文件
    BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(new File(“F:/test2.pdf”)));
    // 将pdf文件先加水印然后输出
    setWatermark(bos, “F:/test.pdf”, “测试user123456789”);
    }

    /**

    @param bos输出文件的位置
    @param input
    原PDF位置
    @param waterMarkName
    页脚添加水印
    @throws DocumentException
    @throws IOException
    /
    public static void setWatermark(BufferedOutputStream bos, String input, String waterMarkName)
    throws DocumentException, IOException {

    PdfReader reader = new PdfReader(input);
    PdfStamper stamper = new PdfStamper(reader, bos);

    // 获取总页数 +1, 下面从1开始遍历
    int total = reader.getNumberOfPages() + 1;
    // 使用classpath下面的字体库
    BaseFont base = null;
    try {
    base = BaseFont.createFont(“/calibri.ttf”, BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
    } catch (Exception e) {
    // 日志处理
    e.printStackTrace();
    }

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

    PdfContentByte content = null;
    for (int i = 1; i < total; i++) {
    // 在内容上方加水印
    content = stamper.getOverContent(i);
    // 在内容下方加水印
    // content = stamper.getUnderContent(i);
    content.saveState();
    content.setGState(gs);

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

    // 设置字体样式
    float ta = 1F, tb = 0F, tc = 0F, td = 1F, tx = 0F, ty = 0F;
    // 设置加粗(加粗)
    ta += 0.25F;
    td += 0.05F;
    ty -= 0.2F;
    // 设置倾斜(倾斜程序自己改)
    tc += 0.8F;
    content.setTextMatrix(ta, tb, tc, td, tx, ty);

    // 设置相对于左下角位置(向右为x,向上为y)
    content.moveText(300F, 5F);
    // 显示text
    content.showText(waterMarkName);

    content.endText();
    content.stroke();
    content.restoreState();
    }

    // 关流
    stamper.close();
    reader.close();
    }
    }
    复制代码
    结果: