最近要做图片水印,公司用的是七牛的服务,所以直接上七牛找这方面资料。
果然很简单,直接再原图的地址后面添加水印参数就可以拿到水印图片(文字不支持emoji),但是这样一来还是漏出了原来图片的地址。
所以这种方式不太符合。然后上网找了下,看到java swing 里面提供这样的实现,然后高高兴兴的写完,调整大小,本地测试完,效果还不错。
然后发上beta后发现水印有问题,在本地中文是可以显示的,但是beta上是不行的。之前遇到的都是关于乱码,很明显就可以看出来,但是这个是中文不出来.
最后排查的感觉是 beta上系统和jdk的font没有宋体的font,下载font,增加到系统的font里 里面顺利解决了此问题。
以下是实现
/** * 添加文字水印 * @param targetImg 目标图片路 * @param pressText 水印文字, * @param fontName 字体名称, 如:宋体 * @param fontStyle 字体样式,如:粗体和斜体(Font.BOLD|Font.ITALIC) * @param fontSize 字体大小,单位为像素 * @param color 字体颜色 * @param x 水印文字距离目标图片左侧的偏移量,如果x<0, 则在正中间 * @param y 水印文字距离目标图片上侧的偏移量,如果y<0, 则在正中间 * @param alpha 透明度(0.0 -- 1.0, 0.0为完全透明,1.0为完全不透明) */ public static BufferedImage pressText(InputStream targetImg, String pressText, String fontName, int fontStyle, Color color, int x, int y, float alpha) { try { log.info("text"+pressText); Image image = ImageIO.read(targetImg); int width = image.getWidth(null); int height = image.getHeight(null); int fontSize = width/20; BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); Graphics2D g = bufferedImage.createGraphics(); g.drawImage(image, 0, 0, width, height, null); g.setFont(new Font(fontName, fontStyle, fontSize)); g.setColor(color); g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, alpha)); int width_1 = fontSize * pressText.length(); g.drawString(new String(pressText.getBytes()), width-x-width_1, height-y); g.dispose(); return bufferedImage; } catch (Exception e) { e.printStackTrace(); return null; } }
其实一看就很明白就是再原图基础上再drawString ,其实好多验证码也是通过这种方式来实现的。
要是想要实现更高级的水印,比如水印是图片就可以通过图片合并来实现,java 中AlphaComposite类是关于2个目标重叠处理的。java的实现都是比较基础的。