继之前的博客: PDF 文件添加二维码水印教程, 图片添加二维码水印教程之后, 对之前的添加二维码水印功能进行完善, 之前的程序生成的二维码图片背景不是透明的, 所以不是很美观, 所以本博客对程序进行完善, 对二维码图片设置背景为透明的, 不过这样美观了, 但是很有可能出现遮住 PDF 文字或者图片的情况, 这种情况会导致二维码不能扫描
参考网上教程, 封装个方法调用
- /**
- * 设置图片背景透明
- * @date 2019 年 6 月 27 日下午 8:46:42
- * @param srcImage
- * @param alpha
- * @return
- * @throws IOException
- */
- public static BufferedImage transparentImage(BufferedImage srcImage,
- int alpha) throws IOException {
- int imgHeight = srcImage.getHeight();// 取得图片的长和宽
- int imgWidth = srcImage.getWidth();
- int c = srcImage.getRGB(3, 3);
- // 防止越位
- if (alpha <0) {
- alpha = 0;
- } else if (alpha> 10) {
- alpha = 10;
- }
- BufferedImage tmpImg = new BufferedImage(imgWidth, imgHeight,BufferedImage.TYPE_4BYTE_ABGR);// 新建一个类型支持透明的 BufferedImage
- for(int i = 0; i < imgWidth; ++i)// 把原图片的内容复制到新的图片, 同时把背景设为透明
- {
- for(int j = 0; j < imgHeight; ++j){
- // 把背景设为透明
- if(srcImage.getRGB(i, j) == c){
- tmpImg .setRGB(i, j, c & 0x00ffffff);
- }
- // 设置透明度
- else{
- int rgb = tmpImg .getRGB(i, j);
- rgb = ((alpha * 255 / 10) << 24) | (rgb & 0x00ffffff);
- tmpImg .setRGB(i, j, rgb);
- }
- }
- }
- return tmpImg ;
- }
然后对之前程序改进, 主要对 bufferImage 进行调整,
- // 设置透明背景
- image = transparentImage(image,10);
- /**
- * 为 PDF 附件添加图片水印
- * @author nicky.ma
- * @date 2019/6/11 12:00:32
- * @param bos 输出文件的位置
- * @param input 输入文件流
- * @param image 水印图片
- */
- public static void setWatermarkForPDF(BufferedOutputStream bos, InputStream input, BufferedImage image)
- throws IOException, DocumentException {
- PdfReader reader = new PdfReader(input);
- PdfStamper stamper = new PdfStamper(reader, bos);
- //int total = reader.getNumberOfPages() + 1;
- PdfContentByte waterMar;
- PdfGState gs = new PdfGState();
- long startTime = System.currentTimeMillis();
- System.out.println("PDF 加图片水印 start");
- //for (int i = 1; i < total; i++) {
- waterMar = stamper.getOverContent(1);// 在内容上方加水印
- //waterMar = stamper.getUnderContent(1);// 在内容下方加水印
- // 设置图片透明度为 0.2f
- //gs.setFillOpacity(0.2f);
- // 设置笔触字体不透明度为 0.4f
- //gs.setStrokeOpacity(0.4f);
- // 开始水印处理
- waterMar.beginText();
- // 设置透明度
- waterMar.setGState(gs);
- // 设置水印字体参数及大小
- //waterMar.setFontAndSize(BaseFont.createFont(BaseFont.HELVETICA, BaseFont.WINANSI, BaseFont.NOT_EMBEDDED), 60);
- // 设置水印对齐方式 水印内容 X 坐标 Y 坐标 旋转角度
- //waterMar.showTextAligned(Element.ALIGN_CENTER, "公司内部文件, 请注意保密!", 500, 430, 45);
- // 设置水印颜色
- //waterMar.setColorFill(BaseColor.GRAY);
- // 设置透明背景
- image = transparentImage(image,10);
- // 创建水印图片
- com.itextpdf.text.Image itextimage = getImage(image,100);
- // 水印图片位置
- itextimage.setAbsolutePosition(2100,1400);
- // 边框固定
- itextimage.scaleToFit(200, 200);
- // 设置旋转弧度
- //image.setRotation(30);// 旋转 弧度
- // 设置旋转角度
- //image.setRotationDegrees(45);// 旋转 角度
- // 设置等比缩放
- //itextimage.scalePercent(90);
- // 自定义大小
- itextimage.scaleAbsolute(200,200);
- // 附件加上水印图片
- waterMar.addImage(itextimage);
- // 完成水印添加
- waterMar.endText();
- // stroke
- waterMar.stroke();
- //}
- long endTime = System.currentTimeMillis();
- System.out.println("PDF 加图片水印 ok 所用时间:"+(endTime-startTime)+"s");
- stamper.close();
- reader.close();
- }
然后还需要修改:
这里不需要设置颜色, 传个 null 就可以
itextImage=com.itextpdf.text.Image.getInstance(bufferedImage,null);
修改后代码, 原来程序参考 PDF 文件添加二维码水印教程
- public static com.itextpdf.text.Image getImage(BufferedImage bufferedImage,float percent){
- com.itextpdf.text.Image itextImage=null;
- try {
- itextImage=com.itextpdf.text.Image.getInstance(bufferedImage,null);
- } catch (BadElementException e) {
- e.printStackTrace();
- } catch (IOException e) {
- e.printStackTrace();
- }
- itextImage.setWidthPercentage(0.1f);
- itextImage.setSpacingAfter(0.1f);
- itextImage.scalePercent(percent);
- itextImage.setBorder(Rectangle.NO_BORDER);
- return itextImage;
- }
上面是针对 PDF 的修缮, 然后再对图片的二维码修改
这里只要调用封装好的方法就可以
- // 设置二维码图片背景透明
- bufferedImage = transparentImage(bufferedImage,10);
参考代码, 具体实现要参考之前代码
- /**
- * 给图片添加水印, 可设置水印图片旋转角度
- * @author mazq
- * @date 2019 年 6 月 12 日下午 2:11:11
- * @param bufferedImage
- * 水印图片
- * @param in
- * 获取附件上传 stream
- * @param os
- * 附件保存 stream
- * @param degree
- * 选择角度
- * @param imgType
- * 上传附件的类型
- */
- public static void setWaterMarkForIMG(BufferedImage bufferedImage, InputStream in, OutputStream os, Integer degree,String imgType) {
- //OutputStream os = null;
- long startTime = System.currentTimeMillis();
- System.out.println("图片附件添加图片水印 start");
- try {
- Image srcImg = ImageIO.read(in);
- 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);
- }
- //float alpha = 0.2f; // 透明度
- //g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, alpha));
- // 水印图象的路径 水印一般为 gif 或者 PNG 的, 这样可设置透明度
- //ImageIcon imgIcon = new ImageIcon(iconPath);
- // 得到 Image 对象.
- //Image img = imgIcon.getImage();
- // 设置二维码图片背景透明
- bufferedImage = transparentImage(bufferedImage,10);
- // 表示水印图片的位置
- g.drawImage(bufferedImage, buffImg.getWidth()-180, 0, null);
- g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER));
- g.dispose();
- //os = new FileOutputStream(targerPath);
- // 生成图片
- ImageIO.write(buffImg, imgType, os);
- long endTime = System.currentTimeMillis();
- System.out.println("图片附件添加图片水印 ok 所用时间:"+(endTime-startTime)+"s");
- } catch (Exception e) {
- e.printStackTrace();
- } finally {
- try {
- if (null != os)
- os.close();
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- }
ps: 本博客只是对之前两篇教程的补充, 请先看之前两篇博客, 再看这篇博客
PDF 文件添加二维码水印教程, 图片添加二维码水印教程
来源: http://www.jianshu.com/p/31a5e381ffc4