java图片增加水印

java水印工具类在请看上面的立即下载

转载请注明出处,谢谢


ImageUtil类代码,使用时调用 markerText 方法就行

import com.sysfunc.core.mybatisplus.exception.BizException;
import com.sysfunc.yyt.cms.dto.FileVO;
import org.apache.commons.lang3.StringUtils;
import org.apache.ibatis.logging.Log;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
import java.util.Base64;
import java.util.List;

public class ImageUtil {

    /**
     * 给图片添加文字水印
     * @param waterMarkContents 水印文字(一个集合一个值对应一条水印)
     * @param buffin         源图像输入流
     * @param fileSuffix     文件后缀名
     * @param fontSize       水印字体大小
     * @param color          水印的字体颜色
     * @param alpha          水印透明度:alpha 必须是范围 [0.0, 1.0] 之内(包含边界值)的一个浮点数字
     * @return byte[]
     */
    public static byte[] markerText(List<String> waterMarkContents, InputStream buffin, String fileSuffix, int fontSize, Color color, float alpha) {
        if (buffin == null) {
            return null;
        }
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        try {
            // 水印之间的横向间隔
            int xmove = 100;
            // 水印之间的纵向间隔
            int ymove = 100;
            Image srcImg = ImageIO.read(buffin);//文件转化为图片
            int srcImgWidth = srcImg.getWidth(null);//获取图片的宽
            int srcImgHeight = srcImg.getHeight(null);//获取图片的高
            // 根据图片高度决定水印文字大小,文字间隔
            if (srcImgHeight <= 500 && srcImgWidth <= 500) {
                fontSize = 20;
                xmove = 50;
                ymove = 50;
            } else if (srcImgHeight > 500 && srcImgHeight <= 1000 && srcImgWidth > 500 && srcImgWidth <= 1000) {
                fontSize = 28;
            } else if (srcImgHeight > 1000 && srcImgHeight <= 2000 && srcImgWidth > 1000 && srcImgWidth <= 2000) {
                fontSize = 50;
                xmove = 150;
                ymove = 150;
            } else if (srcImgHeight > 2000 && srcImgWidth > 2000) {
                fontSize = 95;
                xmove = 300;
                ymove = 300;
            }
            if (srcImgHeight > 3000 && srcImgWidth > 3000) {
                fontSize = 135;
                xmove = 400;
                ymove = 400;
            }
            Font font = new Font("宋体", Font.BOLD, fontSize);
            // 获取其中最长的文字水印的大小
            int maxLen = 0;
            int maxHigh = 0;
            for (int i = 0; i < waterMarkContents.size(); i++) {
                String waterMarkContent = waterMarkContents.get(i);
                int fontlen = getStringLength(font, waterMarkContent);
                if (fontlen >= maxLen) {
                    maxLen = fontlen;
                }
                maxHigh = maxHigh + (i + 1) * fontSize + 10;
            }
            //一个div 每行每列的打印到图片 上
            int rowsNumber = 15;// 图片的高  除以  文字水印的宽  打印的行数(以文字水印的宽为间隔)
            int columnsNumber = 15;//图片的宽 除以 文字水印的宽  每行打印的列数(以文字水印的宽为间隔)
            // 加水印
            BufferedImage bufImg = new BufferedImage(srcImgWidth, srcImgHeight, BufferedImage.TYPE_INT_RGB);
            Graphics2D g = bufImg.createGraphics();//得到画笔
            g.drawImage(srcImg, 0, 0, srcImgWidth, srcImgHeight, null);
            g.setColor(color); //设置水印颜色
            g.setFont(font);//设置字体
            g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, alpha));//设置水印文字透明度
            g.rotate(Math.toRadians(-45),  srcImgWidth,  srcImgHeight);//设置水印旋转

            //至少打印一次
            if (rowsNumber < 1) {
                rowsNumber = 1;
            }
            if (columnsNumber < 1) {
                columnsNumber = 1;
            }

            int yz = 0;
            //遍历每行打印到图片上的个数
            for (int a = 0; a < rowsNumber; a++) {
                int t = 0;
                for (int j = 0; j < waterMarkContents.size(); j++) {
                    String waterMarkContent = waterMarkContents.get(j);
                    int y = (j + 1) * 40 + 10 + t;

                    // 文字叠加,自动换行叠加,注意符号
                    int tempX =  10;
                    int tempY = (-srcImgHeight / 2) - 150 + y + yz;
                    // 单字符长度
                    int tempCharLen = 0;
                    // 单行字符总长度临时计算
                    int tempLineLen = 0;
                    StringBuffer sb = new StringBuffer();
                    for (int i = 0; i < waterMarkContent.length(); i++) {
                        char tempChar = waterMarkContent.charAt(i);
                        tempCharLen = getCharLen(tempChar, g);
                        tempLineLen += tempCharLen;

                        // 和图片的长度进行对应的比较操作
                        if (tempLineLen >= srcImgWidth) {
                            // 长度已经满一行,进行文字叠加
                            g.drawString(sb.toString(), tempX, tempY);
                            t = t + 40;
                            // 清空内容,重新追加
                            sb.delete(0, sb.length());
                            tempY += 40;
                            tempLineLen = 0;
                        }
                        // 追加字符
                        sb.append(tempChar);
                    }
                    // 遍历每列打印到图片上的个数
                    for (int z = 0; z < columnsNumber; z++) {
                        // 最后叠加余下的文字
                        g.drawString(sb.toString(), tempX, tempY);
                        tempX = tempX + maxLen + xmove;
                    }
                }
                yz = yz + maxHigh + ymove;
            }
            g.dispose();// 释放资源
            ImageIO.write(bufImg, fileSuffix, outputStream);
        } catch (Exception e) {
            e.printStackTrace();
            e.getMessage();
        }
        return outputStream.toByteArray();
    }


    public static int getCharLen(char c, Graphics2D g) {
        return g.getFontMetrics(g.getFont()).charWidth(c);
    }


    //得到字符串长度
    public static int getStringLength(Font font, String markContent) {
        if (StringUtils.isEmpty(markContent)) {
            return 0;
        }
        if (null == font) {
            font = new Font(null);
        }
        JLabel label = new JLabel(markContent);
        FontMetrics metrics = label.getFontMetrics(font);
        int width = metrics.stringWidth(label.getText());//文字水印的宽
        return width;
    }
}

 返回的是byte []字节数组,要生成图片可以参考下面方法

// bytes 图片字节数组,path 保存路径
public static boolean byteEncryptFile(byte [] bytes, String path) {
		// 图像数据为空
		if (bytes == null) {
			return false;
		}
		if(path == null || StringUtils.isEmpty(path)){
			return false;
		}

		try {
			createFileParentDir(path, 0);
		} catch (Exception e) {
            System.out.println("创建文件目录失败");
		}

		OutputStream out = null;
		try {
			out = new FileOutputStream(path);
			out.write(bytes);
			out.flush();
			return true;
		} catch (Exception e) {
			System.out.println("保存图片失败");
		}finally {
			if(out!=null){
				try {
					out.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}

		return false;
	}

// 创建文件路径
public static void createFileParentDir(String imgFilePath, Integer num)  {
        try {
            File dirFile = new File(imgFilePath);
            if(!dirFile.getParentFile().exists()
					&& !dirFile.getParentFile().mkdirs()){
                System.out.println("创建文件目录失败!");
            }
        } catch (Exception e) {
        	if (num < 2) {
				num++;
				createFileParentDir(imgFilePath, num);
			} else {
				throw e;
			}
        }
    }

增加水印后的图片,文件大小会比原来的大一点,图片压缩可以参考我另一篇文章

http://t.csdnimg.cn/DYSRw

码字不易,于你有利,勿忘点赞 

北国风光,千里冰封,万里雪飘 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值