实现效果图
这个效果的实现思路是:
1、先准备一张背景图,像素自己去定。像素越高最后生成的图片会更清晰,当然图片也会越大,注意这个背景图一定要是png格式的,要放用户头像的位置要镂空,透明的。
至于为什么要用png格式的,主要是png格式支持无损压缩,能比较好的保存透明信息
2、准备一张任意格式需要置于透明区域的头像。这张图需要根据背景图的像素及镂空区域的大小去调整头像大小。当然这些是可以后端去做的
3、用java实现。先用Graphics画一张干净的图,大小为背景图一致,在根据你的需求,把像素调整后的头像画在指定x,y位置处,大小为头像调整后的长宽。最后在把背景图画在整个画图上,那个镂空区域会把头像显示出来。相当于一个叠加效果。
这里直接把代码贴出来,包括图片的压缩,及最后图片的生成部分。
/***
* 按照指定大小缩放图片
* @param srcImgPath 原图片路径
* @param distImgPath 转换大小后图片路径
* @param width 转换后图片宽度
* @param height 转换后图片高度
*/
public static void resizeImage(String srcImgPath, String distImgPath,int width, int height) throws IOException {
String subfix = "jpg";
subfix = srcImgPath.substring(srcImgPath.lastIndexOf(".") + 1, srcImgPath.length());
File srcFile = new File(srcImgPath);
Image srcImg = ImageIO.read(srcFile);
BufferedImage buffImg = null;
if (subfix.equals("png") || subfix.equals("PNG")) {
buffImg = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
} else {
buffImg = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
}
Graphics2D graphics = buffImg.createGraphics();
graphics.setBackground(Color.WHITE);
graphics.setColor(Color.WHITE);
graphics.fillRect(0, 0, width, height);
graphics.drawImage(srcImg.getScaledInstance(width, height, Image.SCALE_SMOOTH), 0, 0, null);
ImageIO.write(buffImg, subfix, new File(distImgPath));
}
/**
* 图片叠加,底图小图,顶图大图,大图必须为png格式,因为只有png格式支持透明
*
* @param smalllPath 底图
* @param largePath 大图
* @param type 生成图片类型jpg,png...
* @param resultPaht 生成图片保存路径
*/
public static void imageOverlap(String smalllPath, String largePath, String type, String resultPaht,int x,int y) {
try {
log.info("smalllPath: {}",smalllPath);
log.info("largePath: {}",largePath);
log.info("type: {}",type);
log.info("resultPaht: {}",resultPaht);
Assert.hasText(smalllPath, "底图路径为空");
Assert.hasText(largePath, "大图路径为空");
BufferedImage large = getBufferedImageFromUrl(largePath);
BufferedImage small = getBufferedImageFromUrl(smalllPath);
BufferedImage bufferedImage = new BufferedImage(large.getWidth(), large.getHeight(), BufferedImage.TYPE_INT_ARGB);
Graphics g = bufferedImage.getGraphics();
g.drawImage(small, x, y,
small.getWidth(), small.getHeight(), null);
g.drawImage(large, 0, 0,
large.getWidth(), large.getHeight(), null);
ImageIO.write(bufferedImage, type, new File(resultPaht));
} catch (IOException e) {
throw new RuntimeException("合成图片失败", e);
}
}
/**
* 根据图片url获取图片
*
* @param url
* @return
* @throws IOException
*/
public static BufferedImage getBufferedImageFromUrl(String url) throws IOException {
if (url.startsWith("https://") || url.startsWith("http://")) {
return ImageIO.read(new URL(url));
} else {
return ImageIO.read(new File(url));
}
}
public static void main(String[] args) throws Exception {
//这里的489,489分别对应镂空区域的长、宽,需要自己根据自己选定的背景图测量一下
ImagesUtils.resizeImage("/Users/demo/Desktop/6c8809734c15d30f1d97e75d5e64d83a.jpeg","/Users/demo/Desktop/6c8809734c15d30f1d97e75d5e64d83a_1.jpeg",489,489);
//这里的230,578分别对应镂空区域在背景图中的相对位置x,y,需要自己根据自己选定的背景图测量一下
ImagesUtils.imageOverlap("/Users/demo/Desktop/6c8809734c15d30f1d97e75d5e64d83a_1.jpeg",
"/Users/demo/Desktop/background.png",
"png",
"/Users/demo/Desktop/6c8809734c15d30f1d97e75d5e64d83a_3.png",
230,
578
);
}