常用的图像加水印一般是在原图上找一个位置将水印图像置于上方,本质上就是对两幅图像的叠加融合。这里提供两种方式进行图像加水印,一种是直接将水印图像叠加在原图指定位置,一种是将水印通过一定透明度与原图指定位置像素进行融合。
当然在水印融合的同时需要考虑,指定位置叠加水印图像时,水印图像边界不会超过原图边界。另外也可以使用本身带有透明通道的图像作为水印图像,融合之后的图像可以形成镂空水印。
测试图像:
水印图像:
第一种方式实现:
public BufferedImage waterMarkerWithLocation(BufferedImage srcImage,BufferedImage waterMarker,int x,int y) {
int width = srcImage.getWidth();
int height = srcImage.getHeight();
BufferedImage resultImage = new BufferedImage(width, height, srcImage.getType());
for(int i = 0; i < width;i++) {
for(int j = 0; j < height;j++) {
int rgb = srcImage.getRGB(i, j);
if (i > x & i < (waterMarker.getWidth() + x) & j > y & j < (waterMarker.getHeight() + y)) {
rgb = waterMarker.getRGB(i - x, j - y);
}
resultImage.setRGB(i, j, rgb);
}
}
return resultImage;
}
效果:
第二种方式实现:
public BufferedImage waterMarkerWithTransparent(BufferedImage srcImage,BufferedImage waterMarker,double transparent,int x,int y) {
int width = srcImage.getWidth();
int height = srcImage.getHeight();
BufferedImage resultImage = new BufferedImage(width, height, srcImage.getType());
for(int i = 0; i < width;i++) {
for(int j = 0; j < height;j++) {
int rgb = srcImage.getRGB(i, j);
if (i > x & i < (waterMarker.getWidth() + x) & j > y & j < (waterMarker.getHeight() + y)) {
int rgb1 = waterMarker.getRGB(i - x, j - y);
double r = (rgb >> 16) & 0xff;
double g = (rgb >> 8) & 0xff;
double b = rgb & 0xff;
double r1 = (rgb1 >> 16) & 0xff;
double g1 = (rgb1 >> 8) & 0xff;
double b1 = rgb1 & 0xff;
r = (1 - transparent) * r + transparent * r1;
g = (1 - transparent) * g + transparent * g1;
b = (1 - transparent) * b + transparent * b1;
rgb = (255 & 0xff) << 24 | (clamp((int)r) & 0xff) << 16 | (clamp((int)g) & 0xff) << 8 | (clamp((int)b) & 0xff);
}
resultImage.setRGB(i, j, rgb);
}
}
return resultImage;
}
测试效果:
当透明度设置为0.5时
透明度0.2时: