图像合成 - Java实现仿微信群聊头像

java实现仿微信QQ群聊头像图片合成,根据群聊内的用户头像合成群聊头像,九宫格图;效果图如下:

                                

代码实现:

/**
 * 	图片合成(仿微信群聊头像)
 * 
 */
public class ImageUtils {

	/**
	 * 	图片格式:JPG
	 */
	private static final String PICTURE_FORMAT_PNG = "jpg";

	private ImageUtils() {
	}
	
	/**
	 * 	画板的高
	 */
	private static final Integer PICTURE_HEIGHT = 112;
	
	/**
	 * 	画板的宽
	 */
	private static final Integer PICTURE_WIDTH = 112;

	/**
	 * 	生成组合头像
	 * 
	 * @param paths
	 *      	用户图像路径(绝对路径)
	 * @param outImgPath
	 * 			 新图片路径(绝对路径)
	 * @throws IOException
	 */
	public static String getCombinationOfhead(List<String> paths, String outImgPath) throws IOException {
		if (CollectionUtils.isEmpty(paths)) {
			return null;
		}
		List<BufferedImage> bufferedImages = new ArrayList<BufferedImage>();
		// 压缩图片所有的图片生成尺寸
		int imgH = 32;// 图片的高
		int imgW = 32;// 图片的宽
		if (paths.size() <= 4) {
			imgH = imgW = 50;
		}
		boolean flag = false;
		for (int i = 0; i < paths.size(); i++) {
			if (StringUtils.isNotBlank(paths.get(i))) {
				File imgFile = new File(paths.get(i));
				// 判断文件是否存在
				if (imgFile.exists()) {
					flag = true;
					bufferedImages.add(ImageUtils.resizeImage(paths.get(i), imgH, imgW, false));
				}
			}
		}
		if (!flag) {
			return null;
		}
		// BufferedImage.TYPE_INT_RGB可以自己定义可查看API
		BufferedImage outImage = new BufferedImage(PICTURE_WIDTH, PICTURE_HEIGHT, BufferedImage.TYPE_INT_RGB);
		// 生成画布
		Graphics g = outImage.getGraphics();
		Graphics2D g2d = (Graphics2D) g;
		// 设置背景色
		g2d.setBackground(new Color(231, 231, 231));
		// 通过使用当前绘图表面的背景色进行填充来清除指定的矩形。
		g2d.clearRect(0, 0, PICTURE_WIDTH, PICTURE_HEIGHT);
		// 开始拼凑 根据图片的数量判断该生成那种样式的组合头像
		layoutImage(g2d, bufferedImages, imgW);
		String imgName = new Date().getTime() + "_" + new Random().nextInt(120000) + "."
				+ PICTURE_FORMAT_PNG.toLowerCase();
		if (!outImgPath.endsWith("/") && !outImgPath.endsWith("\\")) {
			outImgPath += "/";
		}
		File file = new File(outImgPath);
		if (!file.exists()) {
			file.mkdirs();
		}
		String dir = GlobalStatic.rootDir;
		String imgPath = "";
		if (outImgPath.indexOf(dir) >= 0) {
			imgPath = outImgPath.substring(dir.length());
		}
		ImageIO.write(outImage, PICTURE_FORMAT_PNG, new File(outImgPath + imgName));
		return imgPath + imgName;
	}
	
	/**
	 *	图片布局生成组合图片
	 * @param g2d 画布
	 * @param bufferedImages 图片
	 * @param imgW 图片的宽
	 */
	private static void layoutImage(Graphics2D g2d, List<BufferedImage> bufferedImages, int imgW) {
		int j = 1;
		int k = 1;
		for (int i = 1; i <= bufferedImages.size(); i++) {
			if (bufferedImages.size() == 9) {
				if (i <= 3) {
					g2d.drawImage(bufferedImages.get(i - 1), imgW * (i - 1) + 4 * i, 4, null);
				} else if (i >= 4 && i <= 6) {
					g2d.drawImage(bufferedImages.get(i - 1), imgW * (k - 1) + 4 * k, 4 * 2 + imgW, null);
					++k;
				} else {
					g2d.drawImage(bufferedImages.get(i - 1), imgW * (j - 1) + 4 * j, 4 * 3 + imgW * 2, null);
					j++;
				}
			} else if (bufferedImages.size() == 8) {
				if (i <= 2) {
					g2d.drawImage(bufferedImages.get(i - 1), 18 + imgW * (i - 1) + 4 * i, 4, null);
				} else if (i >= 3 && i <= 5) {
					g2d.drawImage(bufferedImages.get(i - 1), imgW * (k - 1) + 4 * k, 4 * 2 + imgW, null);
					++k;
				} else {
					g2d.drawImage(bufferedImages.get(i - 1), imgW * (j - 1) + 4 * j, 4 * 3 + imgW * 2, null);
					j++;
				}
			} else if (bufferedImages.size() == 7) {
				if (i <= 1) {
					g2d.drawImage(bufferedImages.get(i - 1), 36 + imgW * (i - 1) + 4 * i, 4, null);
				} else if (i >= 2 && i <= 4) {
					g2d.drawImage(bufferedImages.get(i - 1), imgW * (k - 1) + 4 * k, 4 * 2 + imgW, null);
					++k;
				} else {
					g2d.drawImage(bufferedImages.get(i - 1), imgW * (j - 1) + 4 * j, 4 * 3 + imgW * 2, null);
					j++;
				}
			} else if (bufferedImages.size() == 6) {
				if (i <= 3) {
					g2d.drawImage(bufferedImages.get(i - 1), imgW * (i - 1) + 4 * i, 22, null);
				} else {
					g2d.drawImage(bufferedImages.get(i - 1), imgW * (j - 1) + 4 * j, 58, null);
					j++;
				}
			} else if (bufferedImages.size() == 5) {
				if (i <= 2) {
					g2d.drawImage(bufferedImages.get(i - 1), 18 + imgW * (i - 1) + 4 * i, 22, null);
				} else {
					g2d.drawImage(bufferedImages.get(i - 1), imgW * (j - 1) + 4 * j, 58, null);
					j++;
				}
			} else if (bufferedImages.size() == 4) {
				if (i <= 2) {
					g2d.drawImage(bufferedImages.get(i - 1), imgW * (i - 1) + 4 * i, 4, null);
				} else {
					g2d.drawImage(bufferedImages.get(i - 1), imgW * (j - 1) + 4 * j, 58, null);
					j++;
				}
			} else if (bufferedImages.size() == 3) {
				if (i <= 1) {
					g2d.drawImage(bufferedImages.get(i - 1), 31, 4, null);
				} else {
					g2d.drawImage(bufferedImages.get(i - 1), imgW * (j - 1) + 4 * j, 58, null);
					j++;
				}
			} else if (bufferedImages.size() == 2) {
				g2d.drawImage(bufferedImages.get(i - 1), imgW * (i - 1) + 4 * i, 31, null);
			} else if (bufferedImages.size() == 1) {
				g2d.drawImage(bufferedImages.get(i - 1), 31, 31, null);
			}
			// 需要改变颜色的话在这里绘上颜色。可能会用到AlphaComposite类
		}
	}

	/**
	 * 	图片缩放
	 * 
	 * @param filePath
	 *            	图片路径
	 * @param height
	 *            	高度
	 * @param width
	 *            	宽度
	 * @param flag
	 *            	比例不对时是否需要补白
	 */
	@SuppressWarnings("removal")
	public static BufferedImage resizeImage(String filePath, int height, int width, boolean flag) {
		try {
			double ratio = 0; // 缩放比例
			File f = new File(filePath);
			BufferedImage bi = ImageIO.read(f);
			Image itemp = bi.getScaledInstance(width, height, Image.SCALE_SMOOTH);
			// 计算比例
			if ((bi.getHeight() > height) || (bi.getWidth() > width)) {
				if (bi.getHeight() > bi.getWidth()) {
					ratio = (new Integer(height)).doubleValue() / bi.getHeight();
				} else {
					ratio = (new Integer(width)).doubleValue() / bi.getWidth();
				}
				AffineTransformOp op = new AffineTransformOp(AffineTransform.getScaleInstance(ratio, ratio), null);
				itemp = op.filter(bi, null);
			}
			if (flag) {
				BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
				Graphics2D g = image.createGraphics();
				g.setColor(Color.white);
				g.fillRect(0, 0, width, height);
				if (width == itemp.getWidth(null))
					g.drawImage(itemp, 0, (height - itemp.getHeight(null)) / 2, itemp.getWidth(null),
							itemp.getHeight(null), Color.white, null);
				else
					g.drawImage(itemp, (width - itemp.getWidth(null)) / 2, 0, itemp.getWidth(null),
							itemp.getHeight(null), Color.white, null);
				g.dispose();
				itemp = image;
			}
			return (BufferedImage) itemp;
		} catch (IOException e) {
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * 	把图片剪切成圆形图片
	 * @param imgPath 原图路径
	 * @param outPath 处理后图片输出路径
	 * @return
	 * @throws IOException
	 */
	public static String cutoutRoundImage(String imgPath, String outPath) throws IOException {
		BufferedImage bufferedImage = ImageIO.read(new File(imgPath));
		// 根据需要是否使用 BufferedImage.TYPE_INT_ARGB
		BufferedImage bufImg = new BufferedImage(bufferedImage.getWidth(), bufferedImage.getHeight(), BufferedImage.TYPE_INT_RGB);
		Ellipse2D.Double shape = new Ellipse2D.Double(0, 0, bufferedImage.getWidth(), bufferedImage.getHeight());
		Graphics2D g2 = bufImg.createGraphics();
		g2.setBackground(Color.WHITE);
		g2.fill(new Rectangle(bufImg.getWidth(), bufImg.getHeight()));
		g2.setClip(shape);
		// 使用 setRenderingHint 设置抗锯齿
		g2.drawImage(bufferedImage, 0, 0, null);
		g2.dispose();
		String imgName = new Date().getTime() + "_" + new Random().nextInt(120000) + "."
				+ PICTURE_FORMAT_PNG.toLowerCase();
		if (!outPath.endsWith("/") && !outPath.endsWith("\\")) {
			outPath += "/";
		}
		// 输出图片路径
		String imgDir = outPath + imgName;
		try {
			ImageIO.write(bufImg, "jpg", new File(imgDir));
		} catch (IOException e) {
			e.printStackTrace();
		}
		return imgDir;
	}


}

  • 8
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值