JAVA 图片加水印 支持水印换行 水印背景

package com.ifudata.common.utils;
import java.awt.AlphaComposite;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.RenderingHints;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URL;

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

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 功能:图片水印工具类
 *
 * @Date 2022/3/4
 * @Version 1.0
 */


public class ImageRemarkUtil {
	private static final Logger log = LoggerFactory.getLogger(ImageRemarkUtil.class);
    // 水印透明度
    private static float alpha = 0.8f;
    // 水印横向位置
    private static int positionWidth = 100;
    // 水印纵向位置
    private static int positionHeight = 100;
    // 水印文字字体
    private static Font font = new Font("宋体", Font.BOLD, 18);
    // 水印文字颜色
    private static Color color = Color.white;

    /**
     * @param alpha          水印透明度
     * @param positionWidth  水印横向位置
     * @param positionHeight 水印纵向位置
     * @param font           水印文字字体
     * @param color          水印文字颜色
     */
    public static void setImageMarkOptions(float alpha, int positionWidth, int positionHeight, Font font, Color color) {
        if (alpha != 0.0f)
            ImageRemarkUtil.alpha = alpha;
        if (positionWidth != 0)
            ImageRemarkUtil.positionWidth = positionWidth;
        if (positionHeight != 0)
            ImageRemarkUtil.positionHeight = positionHeight;
        if (font != null)
            ImageRemarkUtil.font = font;
        if (color != null)
            ImageRemarkUtil.color = color;
    }

    /**
     * 给图片添加水印图片
     *
     * @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);
            // 1、得到画笔对象
            Graphics2D g = buffImg.createGraphics();
            // 2、设置对线段的锯齿状边缘处理
            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);
            // 3、设置水印旋转
            if (null != degree) {
                g.rotate(Math.toRadians(degree), (double) buffImg.getWidth() / 2, (double) buffImg.getHeight() / 2);
            }
            // 4、水印图片的路径 水印图片一般为gif或者png的,这样可设置透明度
            ImageIcon imgIcon = new ImageIcon(iconPath);
            // 5、得到Image对象。
            Image img = imgIcon.getImage();
            g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, alpha));
            // 6、水印图片的位置
            g.drawImage(img, positionWidth, positionHeight, null);
            g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER));
            // 7、释放资源
            g.dispose();
            // 8、生成图片
            os = new FileOutputStream(targerPath);
            ImageIO.write(buffImg, "JPG", os);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (null != os)
                    os.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 给图片添加水印文字
     *
     * @param logoText   水印文字
     * @param srcImgPath 源图片路径
     * @param targerPath 目标图片路径
     * @throws IOException 
     * @throws FileNotFoundException 
     */
    public static void markImageByText(String logoText, String srcImgPath, String targerPath,double widthRate) throws FileNotFoundException, IOException {
        markImageByText(logoText, srcImgPath, targerPath, null, widthRate );
    }

    /**
     * 给网络图片添加水印文字
     *
     * @param logoText   水印文字
     * @param srcImgPath 源图片路径
     * @param targerPath 目标图片路径
     */
    public static void markNetImageByText(String logoText, String srcImgPath, String targerPath, String watermarkPosition) {
        markNetImageByText(logoText, srcImgPath, targerPath, null, watermarkPosition);
    }

   
    

    

   

    /**
     * 给图片添加水印文字、可设置水印文字的旋转角度
     *
     * @param logoText   水印文字
     * @param srcImgPath 图片地址
     * @param targerPath 存放地址
     * @param degree     旋转角度
     */
    public static void markImageByText(String logoText, String srcImgPath, String targerPath, Integer degree,double widthRate) {
        InputStream is = null;
        OutputStream os = null;
        try {
            // 1、源图片
        	File file =  new File(srcImgPath);
            Image srcImg = ImageIO.read(file);
            BufferedImage buffImg = new BufferedImage(srcImg.getWidth(null), srcImg.getHeight(null), BufferedImage.TYPE_INT_RGB);
            // 2、得到画笔对象
            Graphics2D g = buffImg.createGraphics();
            // 3、设置对线段的锯齿状边缘处理
            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);
            // 4、设置水印旋转
            if (null != degree) {
                g.rotate(Math.toRadians(degree), (double) buffImg.getWidth() / 2, (double) buffImg.getHeight() / 2);
            }
            // 5、设置水印文字颜色
            g.setColor(color);
            // 6、设置水印文字Font
            int size = srcImg.getWidth(null) / 300 * 10;
            if (size == 0) {
                size = 10;
            }
            Font font = new Font("宋体", Font.BOLD, size);
            g.setFont(font);
            // 7、设置水印文字透明度
            g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, alpha));
            // 8、第一参数->设置的内容,后面两个参数->文字在图片上的坐标位置(x,y)
            if(logoText.indexOf("###")>-1){
            	String[] waterMarkContentList = logoText.split("###");
                // 将换行后的文字放入新的集合
            	int startRow = srcImg.getHeight(null)-waterMarkContentList.length*size*1;
            	g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, 0.3f));
            	g.setColor(Color.GRAY);
            	g.setStroke(new BasicStroke(1f));
            	g.fillRect(0, startRow-size*2, srcImg.getWidth(null), startRow+size);
                // 释放对象 透明度设置结束
                g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER));
                g.setColor(Color.WHITE);
                for (int i = 0; i < waterMarkContentList.length; i++) {
//                	JLabel label = new JLabel(waterMarkContentList[i]);/*获取自定义水印信息*/
//                    FontMetrics metrics = label.getFontMetrics(font);
//                    int waterWidth = metrics.stringWidth(label.getText());//文字水印的宽
//                    int rowsNumber = waterWidth/;// 图片的高  除以  文字水印的宽  打印的行数(以文字水印的宽为间隔)
//                    int columnsNumber = width / waterWidth;//图片的宽 除以 文字水印的宽  每行打印的列数(以文字水印的宽为间隔)
                    //g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, 1.0f));
                    g.drawString(waterMarkContentList[i],  (int)Math.floor(srcImg.getWidth(null)*widthRate), startRow+i*size);//画出水印,并设置水印位置
                }

            }else{
            	g.drawString(logoText, (int)Math.floor(buffImg.getWidth()*widthRate), (int)Math.floor(buffImg.getHeight()));
            }
            // 9、释放资源
            g.dispose();
            // 10、生成图片
            String fileTyle=srcImgPath.substring(srcImgPath.lastIndexOf(".")+1,srcImgPath.length()); 
            ByteArrayOutputStream stream = new ByteArrayOutputStream();
            ImageIO.write(buffImg, fileTyle.toUpperCase(), stream);
            os = new FileOutputStream(targerPath);
            ImageIO.write(buffImg, fileTyle.toUpperCase(), os);
            log.info("加水成功");
        } catch (Exception e) {
            log.error("加水印异常:{}",e);
        } finally {
            try {
                if (null != is)
                    is.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
            try {
                if (null != os)
                    os.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    
    /*
     * 中文转unicode编码
     */
    public static String gbEncoding(final String gbString) {
        char[] utfBytes = gbString.toCharArray();
        String unicodeBytes = "";
        for (int i = 0; i < utfBytes.length; i++) {
            String hexB = Integer.toHexString(utfBytes[i]);
            if (hexB.length() <= 2) {
                hexB = "00" + hexB;
            }
            unicodeBytes = unicodeBytes + "\\u" + hexB;
        }
        return unicodeBytes;
    }
   
    public static int getCharLen(char c, Graphics2D g) {
        return g.getFontMetrics(g.getFont()).charWidth(c);
    }

    

    /**
     * 给网络图片添加水印文字、可设置水印文字的旋转角度
     *
     * @param logoText
     * @param srcImgPath
     * @param targerPath
     * @param degree
     */
    public static void markNetImageByText(String logoText, String srcImgPath, String targerPath, Integer degree, String watermarkPosition) {
        InputStream is = null;
        OutputStream os = null;
        try {
            // 1、源图片
            File file = getFile(srcImgPath);
            Image srcImg = ImageIO.read(file);
            int srcWidth = srcImg.getWidth(null);
            int srcHeight = srcImg.getHeight(null);
            double dmarkWidth = srcWidth * 0.2;// 设置水印的宽度为图片宽度的0.2倍
            double dmarkHeight = dmarkWidth * ((double) srcHeight / (double) srcHeight);//强转为double计算宽高比例
            int imarkWidth = (int) dmarkWidth;
            int imarkHeight = (int) dmarkHeight;
            int x;
            int y;
            switch (watermarkPosition) {
                case "topLeft":
                    x = 100;
                    y = 100;
                    break;
                case "topRight":
                    x = srcWidth - imarkWidth;
                    y = 100;
                    break;
                case "bottomLeft":
                    x = 100;
                    y = srcHeight - imarkHeight / 4;
                    break;
                case "bottomRight":
                    x = srcWidth - imarkWidth;
                    y = srcHeight - imarkHeight / 4;
                    break;
                default:
                    x = srcWidth - imarkWidth;
                    y = srcHeight - imarkHeight / 4;
                    break;
            }
            BufferedImage buffImg = new BufferedImage(srcImg.getWidth(null), srcImg.getHeight(null), BufferedImage.TYPE_INT_RGB);
            // 2、得到画笔对象
            Graphics2D g = buffImg.createGraphics();
            // 3、设置对线段的锯齿状边缘处理
            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);
            // 4、设置水印旋转
            if (null != degree) {
                g.rotate(Math.toRadians(degree), (double) buffImg.getWidth() / 2, (double) buffImg.getHeight() / 2);
            }
            // 5、设置水印文字颜色
            g.setColor(color);
            // 6、设置水印文字Font
            g.setFont(font);
            // 7、设置水印文字透明度
            g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, alpha));
            // 8、第一参数->设置的内容,后面两个参数->文字在图片上的坐标位置(x,y)
            g.drawString(logoText, x, y);
            // 9、释放资源
            g.dispose();
            // 10、生成图片
            os = new FileOutputStream(targerPath);
            ImageIO.write(buffImg, "JPG", os);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (null != is)
                    is.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
            try {
                if (null != os)
                    os.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

   

    /**
     * 将网络图片转file文件
     *
     * @param url
     * @return
     */
    public static File getFile(String url) {
        //对本地文件命名
        String fileName = url.substring(url.lastIndexOf("."));
        File file = null;
        URL urlfile;
        InputStream inStream = null;
        OutputStream os = null;
        try {
            file = File.createTempFile("net_url", fileName);
            //下载
            urlfile = new URL(url);
            inStream = urlfile.openStream();
            os = new FileOutputStream(file);
            int bytesRead = 0;
            byte[] buffer = new byte[8192];
            while ((bytesRead = inStream.read(buffer, 0, 8192)) != -1) {
                os.write(buffer, 0, bytesRead);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (null != os) {
                    os.close();
                }
                if (null != inStream) {
                    inStream.close();
                }
                if (null != file) {
                    file.deleteOnExit(); //程序退出时删除临时文件
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return file;
    }

    
  public static void main(String[] args) throws FileNotFoundException, IOException {
	  ImageRemarkUtil.markImageByText("ssss###aaa###ssss###aaa###sssssssssssssssssssssssssssssssssssssssssssssssss", "d:/11111.png", "d:/11112.png",0.02);
  }
  
}

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

lb8607

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值