有的时候,业务中需要将两张图片进行叠加,比如:国庆节的时候流行把国旗放在头像的右下角以表对国家的热爱;
该种效果其实算法很简单; 现在也有现成的工具,比如opencv; 这里可以不使用opencv;直接用代码就可以实现;
这其实涉及到一个分层的概念,也就是说把两张即将叠加的图片分为上下两层; 上面的图层会遮住下面的图层,也就是说
把需要被覆盖的位置的所有像素变成最上面图片的像素颜色即可;
该算法就是抛砖引玉,只实现右下角的覆盖,对于覆盖其它位置的可以自行设置偏移量;
原图如下:
效果图如下:
核心代码如下:
/**
* 增加图标抽象类
*/
public abstract class AbstractAddFlag extends AbstractPictureFilter {
@Override
public Color filterColor(Color color) {
return null;
}
@Override
public BufferedImage pictureAddFilter(BufferedImage image) {
return pictureAddFlag(image,getFlagImage());
}
/**
* 增加icon
* 默认右下角
* 主要是对rgb坐标进行循环,
* 将icon的像素直接覆盖底层图片
* @param image 原图片
* @param flagImage icon图片
* @return
*/
public BufferedImage pictureAddFlag(BufferedImage image, BufferedImage flagImage) {
if (flagImage == null) {
return image;
}
BufferedImage newImage = new BufferedImage(image.getWidth(),image.getHeight(),BufferedImage.TYPE_4BYTE_ABGR);
int[] imageRGB = new int[image.getWidth() * image.getHeight()];
imageRGB = image.getRGB(0,0,image.getWidth(),image.getHeight(),imageRGB,0,image.getWidth());
newImage.setRGB(0,0,image.getWidth(),image.getHeight(),imageRGB,0,image.getWidth());
int flagImageX = flagImage.getWidth() -1;
for (int x = newImage.getWidth() - 1; x >= flagImage.getWidth(); x--) {
int flagImageY = flagImage.getHeight() -1;
for (int y = newImage.getHeight() - 1; y >= flagImage.getHeight(); y--) {
if(flagImageX < 0 || flagImageY < 0 ){
break;
}
newImage.setRGB(x,y,flagImage.getRGB(flagImageX,flagImageY));
flagImageY -- ;
}
flagImageX --;
}
return newImage;
}
/**
* 获得小图片的文件
* 可为网络文件
* 可为本地文件
* @return file
*/
protected abstract BufferedImage getFlagImage();
}
@Component(value = "addChinaFlag")
public class AddChinaFlag extends AbstractAddFlag {
private static final Log log = LogFactory.getLog(AddChinaFlag.class);
@Override
protected BufferedImage getFlagImage() {
File file = new File("国旗.jpg");
try {
return ImageIO.read(file);
} catch (IOException e) {
log.info("获得国旗icon失败",e);
}
return null;
}
}