给图片增加盲水印
亲测有效,有任何问题可以留言
/**
* 添加文字水印的方法
* 带下超过20M 和图片像素超过 9999的直接拒绝
*
* @param pressText 要添加的文字
* @param fileId 文件Id
* @param fontName 文字的字体名称
* @param fontSize 文字的大小
* @param fontColor 文字的颜色
* @return
*/
public void generateText(InputStream inputStream, String pressText, String fontName, int fontSize, String fontColor, int dissolve, Integer watermarkDegree, int batch, HttpServletResponse response, int inline) {
try {
BufferedImage bgImage = ImageIO.read(inputStream);
long startTime = System.currentTimeMillis();
int wideth = bgImage.getWidth(null);
int height = bgImage.getHeight(null);
BufferedImage image = new BufferedImage(wideth, height, BufferedImage.TYPE_INT_RGB);
Graphics2D g = image.createGraphics();
g.drawImage(bgImage, 0, 0, wideth, height, null);
//设置字体大小、颜色等
Font font = new Font(fontName, Font.PLAIN, fontSize);
g.setColor(parseToColor(fontColor));
g.setFont(font);
//不加的话文字水印有锯齿
RenderingHints rh = new RenderingHints(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
rh.put(RenderingHints.KEY_STROKE_CONTROL
, RenderingHints.VALUE_STROKE_PURE);
rh.put(RenderingHints.KEY_ALPHA_INTERPOLATION
, RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY);
g.setRenderingHints(rh);
// 设置水印旋转角度
if (null != watermarkDegree) {
// 设置水印旋转
g.rotate(Math.toRadians(watermarkDegree), (double) image.getWidth() / 2, (double) image.getHeight() / 2);
}
//设置是否平铺
if (PaintModeEnum.TILED.eq(batch)) {
// 设置水印透明度
g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, dissolve / 100f));
String[] waterMarkContents = pressText.split("\\|\\|");
// 获取其中最长的文字水印的大小
int maxLen = 0;
int maxHigh = 0;
for (int i = 0; i < waterMarkContents.length; i++) {
pressText = waterMarkContents[i];
int fontlen = getWatermarkLength(pressText, g);
if (fontlen >= maxLen) {
maxLen = fontlen;
}
maxHigh = maxHigh + (i + 1) * fontSize + 10;
}
// 文字长度相对于图片宽度应该有多少行
int line = wideth * 2 / maxLen;
int co = height * 2 / maxHigh;
int yz = 0;
// 填充Y轴方向
for (int a = 0; a < co; a++) {
int t = 0;
for (int j = 0; j < waterMarkContents.length; j++) {
pressText = waterMarkContents[j];
int y = (j + 1) * fontSize + 10 + t;
// 文字叠加,自动换行叠加,注意符号
int tempX = -wideth / 2;
int tempY = -height / 2 + y + yz;
// 单字符长度
int tempCharLen = 0;
// 单行字符总长度临时计算
int tempLineLen = 0;
StringBuffer sb = new StringBuffer();
for (int i = 0; i < pressText.length(); i++) {
char tempChar = pressText.charAt(i);
tempCharLen = getCharLen(tempChar, g);
tempLineLen += tempCharLen;
// 和图片的长度进行对应的比较操作
if (tempLineLen >= wideth) {
// 长度已经满一行,进行文字叠加
g.drawString(sb.toString(), tempX, tempY);
t = t + fontSize;
// 清空内容,重新追加
sb.delete(0, sb.length());
tempY += fontSize;
tempLineLen = 0;
}
// 追加字符
sb.append(tempChar);
}
// 填充X轴
for (int z = 0; z < line; z++) {
// 最后叠加余下的文字
g.drawString(sb.toString(), tempX, tempY);
tempX = tempX + maxLen + 80;
}
}
yz = yz + maxHigh + 80;
}
} else {
// 设置水印透明度
g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, dissolve / 100f));
g.drawString(pressText, wideth / 2, height / 2);
}
g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER));
g.dispose();
log.info("增加显示水印 耗时 cost :{}", System.currentTimeMillis() - startTime);
String fileNameEncoder = URLEncoder.encode("target.jpg", "UTF-8");
fileNameEncoder = fileNameEncoder.replaceAll("\\+", "%20");
response.setContentType(FileNameUtil.getFileHttpContentType("target.jpg"));
//嵌入到浏览器中打开
if (InlineEnum.URL_INLINE.eq(inline)) {
response.setHeader("Content-Disposition", "inline;Filename=" + fileNameEncoder);
} else {
response.setHeader("Content-Disposition", "attachment;Filename=" + fileNameEncoder);
}
//设置缓存
response.setHeader("Cache-Control", "public, max-age=31536000");
response.setHeader("Pragma", "Pragma");
OutputStream output = response.getOutputStream();
ImageIO.write(image, "jpg", output);
} catch (Exception e) {
log.error("增加显示水印失败 e :{}", e);
}
}
基本所有的显示水印的要求都能满足 !!!
原创不易,多谢关注 !