java实现添加图片水印和文字水印
我们经常会在一些图片或者图片上看到某某公司或品牌的水印,那么我们可不可以自己在喜欢的图片或文件上添加水印呢?答案当然是没问题。
我们先来看看图片水印:
----------------------------图片水印----------------------------
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(); } } } }
效果展示:
(免费视频教程:java视频教程)
------------------------------PDF水印(itext添加水印)----------------------------
在这里就同时给PDF添加文字水印和图片水印(每一页都添加一个文字水印和图片水印)
依赖的包:
<dependencies> <dependency> <groupId>com.lowagie</groupId> <artifactId>itextasian</artifactId> <version>1.0</version> </dependency> <dependency> <groupId>com.lowagie</groupId> <artifactId>itext</artifactId> <version>2.1.7</version> </dependency> </dependencies>
具体代码:
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(); } }
结果展示:
相关推荐:java入门教程
Atas ialah kandungan terperinci java实现添加图片水印和文字水印. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Alat AI Hot

Undresser.AI Undress
Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover
Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Undress AI Tool
Gambar buka pakaian secara percuma

Clothoff.io
Penyingkiran pakaian AI

Video Face Swap
Tukar muka dalam mana-mana video dengan mudah menggunakan alat tukar muka AI percuma kami!

Artikel Panas

Alat panas

Notepad++7.3.1
Editor kod yang mudah digunakan dan percuma

SublimeText3 versi Cina
Versi Cina, sangat mudah digunakan

Hantar Studio 13.0.1
Persekitaran pembangunan bersepadu PHP yang berkuasa

Dreamweaver CS6
Alat pembangunan web visual

SublimeText3 versi Mac
Perisian penyuntingan kod peringkat Tuhan (SublimeText3)

Topik panas

Panduan untuk Nombor Smith di Jawa. Di sini kita membincangkan Definisi, Bagaimana untuk menyemak nombor smith di Jawa? contoh dengan pelaksanaan kod.

Dalam artikel ini, kami telah menyimpan Soalan Temuduga Spring Java yang paling banyak ditanya dengan jawapan terperinci mereka. Supaya anda boleh memecahkan temuduga.

Java 8 memperkenalkan API Stream, menyediakan cara yang kuat dan ekspresif untuk memproses koleksi data. Walau bagaimanapun, soalan biasa apabila menggunakan aliran adalah: bagaimana untuk memecahkan atau kembali dari operasi foreach? Gelung tradisional membolehkan gangguan awal atau pulangan, tetapi kaedah Foreach Stream tidak menyokong secara langsung kaedah ini. Artikel ini akan menerangkan sebab -sebab dan meneroka kaedah alternatif untuk melaksanakan penamatan pramatang dalam sistem pemprosesan aliran. Bacaan Lanjut: Penambahbaikan API Java Stream Memahami aliran aliran Kaedah Foreach adalah operasi terminal yang melakukan satu operasi pada setiap elemen dalam aliran. Niat reka bentuknya adalah

Panduan untuk TimeStamp to Date di Java. Di sini kita juga membincangkan pengenalan dan cara menukar cap waktu kepada tarikh dalam java bersama-sama dengan contoh.

Kapsul adalah angka geometri tiga dimensi, terdiri daripada silinder dan hemisfera di kedua-dua hujungnya. Jumlah kapsul boleh dikira dengan menambahkan isipadu silinder dan jumlah hemisfera di kedua -dua hujungnya. Tutorial ini akan membincangkan cara mengira jumlah kapsul yang diberikan dalam Java menggunakan kaedah yang berbeza. Formula volum kapsul Formula untuk jumlah kapsul adalah seperti berikut: Kelantangan kapsul = isipadu isipadu silinder Dua jumlah hemisfera dalam, R: Radius hemisfera. H: Ketinggian silinder (tidak termasuk hemisfera). Contoh 1 masukkan Jejari = 5 unit Ketinggian = 10 unit Output Jilid = 1570.8 Unit padu menjelaskan Kirakan kelantangan menggunakan formula: Kelantangan = π × r2 × h (4

PHP dan Python masing -masing mempunyai kelebihan sendiri, dan pilihannya harus berdasarkan keperluan projek. 1.Php sesuai untuk pembangunan web, dengan sintaks mudah dan kecekapan pelaksanaan yang tinggi. 2. Python sesuai untuk sains data dan pembelajaran mesin, dengan sintaks ringkas dan perpustakaan yang kaya.

PHP adalah bahasa skrip yang digunakan secara meluas di sisi pelayan, terutamanya sesuai untuk pembangunan web. 1.PHP boleh membenamkan HTML, memproses permintaan dan respons HTTP, dan menyokong pelbagai pangkalan data. 2.PHP digunakan untuk menjana kandungan web dinamik, data borang proses, pangkalan data akses, dan lain -lain, dengan sokongan komuniti yang kuat dan sumber sumber terbuka. 3. PHP adalah bahasa yang ditafsirkan, dan proses pelaksanaan termasuk analisis leksikal, analisis tatabahasa, penyusunan dan pelaksanaan. 4.Php boleh digabungkan dengan MySQL untuk aplikasi lanjutan seperti sistem pendaftaran pengguna. 5. Apabila debugging php, anda boleh menggunakan fungsi seperti error_reporting () dan var_dump (). 6. Mengoptimumkan kod PHP untuk menggunakan mekanisme caching, mengoptimumkan pertanyaan pangkalan data dan menggunakan fungsi terbina dalam. 7

Java ialah bahasa pengaturcaraan popular yang boleh dipelajari oleh pembangun pemula dan berpengalaman. Tutorial ini bermula dengan konsep asas dan diteruskan melalui topik lanjutan. Selepas memasang Kit Pembangunan Java, anda boleh berlatih pengaturcaraan dengan mencipta program "Hello, World!" Selepas anda memahami kod, gunakan gesaan arahan untuk menyusun dan menjalankan program, dan "Hello, World!" Pembelajaran Java memulakan perjalanan pengaturcaraan anda, dan apabila penguasaan anda semakin mendalam, anda boleh mencipta aplikasi yang lebih kompleks.
