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

news/2024/11/24 3:12:58/

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-fileupload</groupId><artifactId>commons-fileupload</artifactId><version>1.5</version>
</dependency>

http://www.ppmy.cn/news/297610.html

相关文章

String[ ]数组转Integer[ ]数组+数组正序、倒序排序

1、String [] 转 Integer [] 1. 使用Arrays.stream()方法将String数组转换为Stream<String>对象 2. 使用map()方法将每个String元素转换为Integer类型 3. 使用toArray()方法将Stream<Integer>对象转换为Integer[]数组 String[] stringArray {"1", "…

Intel 82599 双万兆光口网卡的多VLan设置(Dante Controller可用)

设备管理需要自动控制电脑访问多个网络vlan&#xff0c;考察了万兆双网口的咸鱼市场&#xff0c;选择最普遍的Intel 82599ES方案的双万兆网卡尝试 Win 10驱动 Intel网站下载&#xff1a;https://www.intel.com/content/www/us/en/download/18293/intel-network-adapter-driv…

LeetCode刷题汇总 - top100及高频面试题

引言 最近两三周都没有更新博客了&#xff0c;主要是因为平常工作比较忙&#xff0c;那么从今天开始我就要重新开始更新博客&#xff0c;在没更新的这段时间里面&#xff0c;我当然也是没有停止学习&#xff0c;主要是平常练练力扣的高频面试题。 当然这些高频题只是算法很小的…

解决 Linux /dev/mapper/ubuntu--vg-ubuntu--lv 磁盘空间不足的问题

之前在 VMware 安装 Ubuntu Server 的时候 磁盘分区 选择了 LVM&#xff0c;所以系统根目录默认占用磁盘大小只有4G&#xff0c;在安装软件时发现磁盘空间4G已经无法满足&#xff0c;所以需要利用 LVM 对磁盘进行扩容 使用 Docker 拉取 MySQL 镜像时发现磁盘空间不够&#xff…

我的第一道web类CTF题——一起来撸猫o(=•ェ•=)m

链接&#xff1a;BUUCTF在线评测 (buuoj.cn)https://buuoj.cn/challenges#%5B%E6%9E%81%E5%AE%A2%E5%A4%A7%E6%8C%91%E6%88%98%202019%5DHavefun 第一步&#xff0c;打开网址 打开网址后按F12查看。 第二步&#xff0c;看见一段被注释掉的PHP语言。 eg: 开始以为直接找到flag …

nginx热升级

做web开发和做运维的都知道nginx是一个非常优秀的web服务器和反向代理服务器&#xff0c;它优秀的多进程架构保证其稳定的运行&#xff0c;还为我们提供了热升级功能&#xff08;不影响客户端请求的处理&#xff09;。 1. nginx热升级介绍 nginx热升级也就是在不影响客户端请…

RK3288 双网口支持

SDK版本&#xff1a; RK3288_ANDROID7.1_TABLET-SDK_V1.00_20170629 USB Ethernet &#xff1a;RTL8152B-VB-CG 直接上代码补丁 diff --git a/device/rockchip/rk3288/rk3288.mk b/device/rockchip/rk3288/rk3288.mk old mode 100644 new mode 100755 index da27247..6954e56…

RFID低频卡-125K门禁卡种类

在物联网领域&#xff0c;常用的RFID芯片&#xff0c;根据频率高低分为低频芯片和高频芯片。 低频芯片&#xff0c;频率125KHz 高频芯片&#xff0c;频率13.56MHz&#xff0c;即NFC频率。 频率是射频领域最核心的参数&#xff0c;天线必须匹配到中心频率&#xff0c;信号才好…