Graphices2D合成图片流程和注意事项

1.把需要合成的两个(多个)图片转成BufferedImage

BufferedImage bgImgBuf = ImageIO.read("背景图");
BufferedImage qrImgBuf = ImageIO.read("二维码图");

2.合成

BufferedImage genBufImg = overlyingImage(
		bgImgBuf,
		qrImgBuf, 
		his.getQrWH(),
		his.getQrX(),
		his.getQrY(), 
		Float.parseFloat(his.getQrA()));

/** 
* @param bgImgBuf 源文件(BufferedImage) 
* @param qrImgBuf   二维码文件(BufferedImage) 
* @param qrWH     二维码的宽高 
* @param x       距离右下角的X偏移量 
* @param y       距离右下角的Y偏移量 
* @param qrA   透明度, 选择值从0.01.0: 完全透明完全不透明 
* @return BufferedImage * @Title: 构造合并图片
*/
public static BufferedImage overlyingImage(BufferedImage bgImgBuf, BufferedImage qrImgBuf, int qrWH, int x, int y, float qrA) {
	int bgImgW = bgImgBuf.getWidth(); 
	int bgImgH = bgImgBuf.getHeight(); 
	//创建Graphics2D对象,用在底图对象上绘图
	Graphics2D g2d = bgImgBuf.createGraphics();    
	//g2d.setBackground(Color.WHITE);  
	//在图形和图像中实现混合和透明效果
	g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, qrA));    
//绘制 
	g2d.drawImage(qrImgBuf, bgImgW - qrWH - x, bgImgH - qrWH - y, qrWH, qrWH, null);    
	g2d.dispose();    
	
	return bgImgBuf;
}

3.注意事项

合并只是得到一个BufferedImage的文件,前端是不能直接展示出来这个图片的,需要做转换处理,把BufferedImage 转成MultipartFile(或者File)。
注意事项:BufferedImage不能直接转成MultipartFile,转出来的MultipartFile是由问题的(至于有什么问题,可以Debug就能看到问题了)。
流程如下:

3.1 把BufferedImage转成File

String ext = FileUtil.extName(his.getBgImg());
String fileName = his.getNo().concat(".").concat(ext);
String path = ClassLoader.getSystemResource("").getPath().concat("temp_file");
logger.info("临时文件存储路径:{}", path);
//把合成的海报先临时保存到项目的resources/temp_file下
String filePath = path.concat("/").concat(fileName);
File file = new File(filePath);
ImageIO.write(genBufImg, ext, file);
logger.info("图片保存:{}", file.exists());

3.2 把File存到项目目录下(或者磁盘)

String ext = FileUtil.extName(his.getBgImg());
String fileName = his.getNo().concat(".").concat(ext);
String path = ClassLoader.getSystemResource("").getPath().concat("temp_file");
logger.info("临时文件存储路径:{}", path);
//把合成的海报先临时保存到项目的resources/temp_file下
String filePath = path.concat("/").concat(fileName);
File file = new File(filePath);
ImageIO.write(genBufImg, ext, file);
logger.info("图片保存:{}", file.exists());

3.3 从项目目录(或磁盘)把File读取出来(一般这步直接使用上面3.2的File即可

File file = new File(filePath);

3.4 把读取到的File转成MultipartFile

public static MultipartFile file2MultipartFile(File file) {
	return new CommonsMultipartFile(createFileItem(file)); 
}

private static FileItem createFileItem(File file){
	DiskFileItemFactory factory = new DiskFileItemFactory(16, null); 
	FileItem fileItem = factory.createItem("testField", "text/plain", true, file.getName()); 
	int byteRead = 0;   
	byte[] buffer = new byte[8192];
	try (FileInputStream fis = new FileInputStream(file); OutputStream os = fileItem.getOutputStream()) {  
		while ((byteRead = fis.read(buffer, 0, 8192)) != -1) {
			os.write(buffer, 0, byteRead);   
		}      
		os.close();     
		fis.close();   
	} catch (IOException e) {
		e.printStackTrace();  
	}   
	return fileItem;
}

3.6 MultipartFile上传到七牛云(或者服务器)得到可展示的URL(这步如果不需要,可以不写)

//如有需求

3.7 删除项目目录(磁盘)的源文件(如有必要)

file.delete();

其实,3.1、3.2、3.3、3.4这几步都是解决BufferedImage不能直接转成MultipartFile这个问题。

如果合成的图片由遮罩(阴影),那么一定是这个原因,在把合成得到的BufferedImage转成File存到时,有这么一个方法ImageIO.write(genBufImg, ext, file),第二个参数是图片的后缀,必须使用图片的原后缀,不能修改,比如,原来图片的后缀是png,这里你写死成jpg,就会出现这个问题;

4.需要引入的包

<dependency>
	<groupId>commons-fileuploadgroupId>
	<artifactId>commons-fileuploadartifactId>
	<version>1.5version>
dependency>

你可能感兴趣的:(java,开发语言)