java 处理图片图片合成
最近写了一个java的图片合成相关的项目,真的是一踩一个坑,下面博主说说遇见的一些坑和怎么解决的这些问题。 本文主要讲图片合成,加文字还是比较简单的。
先讲下我的需求,把一张图片盖到另外一张图片上面,然后在图片上加上字
第一个版本
最开始的时候我用的是thumbnailator工具包,如上图效果
但是问题来了,这张图有很大的问题,两个图都是透明度发生了变化。
第二个版本
使用java自带的Graphics2D
代码如下
String blackPath = "";String fontPath = "";// 水印图URL frontUrl = new URL(fontPath);// 地图URL blackUrl = new URL(blackPath);BufferedImage blackImage = ImageIO.read(blackUrl );BufferedImage frontImage = ImageIO.read(frontUrl );// 拉伸下Thumbnails.Builder<BufferedImage> of = Thumbnails.of(blackImage).size(750, 750);blackImage = of.asBufferedImage();Graphics2D g2d = blackImage.createGraphics();// 在地图上绘制水印g2d.drawImage(frontImage, 0, 0, 750, 750, null);g2d.dispose();
这个代码可以合成图片,但是有两个问题
- 图片失真
- 图片合成后在叠加的部分颜色发生了变化
第三个版本
使用Toolkit.getDefaultToolkit() 读取image
图片image转化为bufferImage方法
public static BufferedImage toBufferedImage(Image image) {if (image instanceof BufferedImage) {return (BufferedImage)image;}// This code ensures that all the pixels in the image are loadedimage = new ImageIcon(image).getImage();// Determine if the image has transparent pixels; for this method's// implementation, see e661 Determining If an Image Has Transparent Pixels//boolean hasAlpha = hasAlpha(image);// Create a buffered image with a format that's compatible with the screenBufferedImage bimage = null;GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();try {// Determine the type of transparency of the new buffered imageint transparency = Transparency.OPAQUE;/* if (hasAlpha) {transparency = Transparency.BITMASK;}*/// Create the buffered imageGraphicsDevice gs = ge.getDefaultScreenDevice();GraphicsConfiguration gc = gs.getDefaultConfiguration();bimage = gc.createCompatibleImage(image.getWidth(null), image.getHeight(null), transparency);} catch (HeadlessException e) {// The system does not have a screen}if (bimage == null) {// Create a buffered image using the default color modelint type = BufferedImage.TYPE_INT_RGB;//int type = BufferedImage.TYPE_3BYTE_BGR;//by wang/*if (hasAlpha) {type = BufferedImage.TYPE_INT_ARGB;}*/bimage = new BufferedImage(image.getWidth(null), image.getHeight(null), type);}// Copy image to buffered imageGraphics g = bimage.createGraphics();// Paint the image onto the buffered imageg.drawImage(image, 0, 0, null);g.dispose();return bimage;}
图片合成方法
String blackPath = "";String fontPath = "";// 水印图URL frontUrl = new URL(fontPath);// 地图URL blackUrl = new URL(blackPath);// 读取背景图Image blackImage = Toolkit.getDefaultToolkit().getImage(blackUrl);// 读取水印图Image frontImage = Toolkit.getDefaultToolkit().getImage(frontUrl);BufferedImage image = toBufferedImage(blackImage);// 拉伸下,Thumbnails.Builder<BufferedImage> of = Thumbnails.of(image).size(750, 750);image = of.asBufferedImage();Graphics2D g2d = image.createGraphics();// 在地图上绘制水印g2d.drawImage(frontImage, 0, 0, 750, 750, null);g2d.dispose();
改进之后图片的失真问题解决了, 图片的颜色变化问题也解决了。
但是新问题又来了,合成的时候有时候成功有时候失败
上面这个问题真的是日了狗了。
在这里抱怨一下,程序员不怕不成功的代码,就怕这代码有时候成功,有时候失败,最后我找到问题所在,这个读取image的方法它不是同步的,也就是说必须把它变成同步。
第四个版本
这个方法是把图片读取从异步变成同步
@Slf4j
public class MediaTrackerRunner extends Applet implements Runnable
{int speed = 5;private String path;public MediaTrackerRunner(String path) throws HeadlessException{this.path = path;}@Overridepublic void init(){super.init();}@Overridepublic void run(){while (true){repaint(); // 重绘try{// 休眠,休眠时间根据图像显示速度计算Thread.sleep(1000 / speed);}catch (InterruptedException e){throw new RuntimeException(e);}}}/*** [简要描述]:<br/> 根据图片路径读取图片, 同步* [详细描述]:<br/>* @return java.awt.Image* 2020/12/9 - 19:05**/public Image execute(){MediaTracker tracker = new MediaTracker(this);URL fontUrl = null;try{fontUrl = new URL(path);}catch (MalformedURLException e){e.printStackTrace();}// 此方法为异步Image fotImage = Toolkit.getDefaultToolkit().getImage(fontUrl);tracker.addImage(fotImage, 1);try{tracker.waitForAll();}catch (InterruptedException e){e.printStackTrace();}return fotImage;}}
楼主在本地添加参数-Djava.awt.headless=false调试并且运行成功,但是一上linux服务,fuck又不行
最后报错
Can’t connect to X11 window server using ‘:0.0′ as the value of the DISPLAY variable
楼主去研究了下,最后得出结论,使用这个api必须系统要支持图形化操作界面
当到这里的时候,楼主想死的心都有了
最后改进
不能使用同步的方法了,经过我观察,总是水印图加载部分,或者加载失败。最后试了试水印图使用ImageIo.read方法来读取,代码如下
这个toBufferedImage方法在上面
String blackPath = "";String fontPath = "";// 水印图URL frontUrl = new URL(fontPath);// 地图URL blackUrl = new URL(blackPath);// 读取水印图Image frontImage = ImageIO.read(frontUrl);// 读取背景图Image blackImage = Toolkit.getDefaultToolkit().getImage(blackUrl);BufferedImage image = toBufferedImage(blackImage);// 拉伸下,Thumbnails.Builder<BufferedImage> of = Thumbnails.of(image).size(750, 750);image = of.asBufferedImage();Graphics2D g2d = image.createGraphics();// 在地图上绘制水印g2d.drawImage(frontImage, 0, 0, 750, 750, null);g2d.dispose();
最后附图
最后还真的让楼主成功了,这些问题记录下,顺便述说下楼主的辛酸。如果哪位大佬有更好的方法,或者更好的工具包出来,欢迎指点。
java 处理图片图片合成相关推荐
- JAVA操作图片/合成/电子盖章等
JAVA操作图片/合成/电子盖章等 /**** @param mainFile* @param file1* @param f 透明度 最大为1* @param response* @return* ...
- Java 实现图片合成
2019独角兽企业重金招聘Python工程师标准>>> 图片合成 利用Java的绘图方法,实现图片合成 在开始之前,先定一个小目标,我们希望通过图片合成的方式,创建一个类似下面样式的 ...
- java进行图片合成以及写入自定义字体
由于工作需要做了一个利用java的Graphics2D进行图片合成且在图片上写入自定义字体文字的小功能, 那就顺便记录一些痕迹,有什么不好的地方请见谅 public static void main( ...
- linux centos java kumo图片合成文字 词云插件 字体乱码问题
linux下安装微软雅黑字体库 或者其他字体 jieba 词云 kumo相关 百度随便找个ttf安装就行 用winscp直接切目录 /usr/share/fonts/ 放入*.ttf字体文件 先看看f ...
- Java实现图片合成
功能 竖向合成多张大小不一致的图片,以最宽图片的为宽为合成后的宽度, 高为所有图片的总高度.图片宽度没有达到合成的宽度则填充部分使用白色画布填充. 代码 /*** 多张图片进行竖向合并成一张图片* @ ...
- java实现图片合成gif图——输出到具体路径或流数据上传
一.多图片转gif 转存到输出流 /*** 多图片转gif 转存到输出流** @param imageList* @param os* @throws IOException*/private sta ...
- JAVA 由图片合成gif文件
1.需要四个类,直接应用到项目中,不需要做太多改动,除了导包: 2.jpgToGif函数需要传入两个参数,第一个参数为要合成的图片路径数组,第二个参数为合成的GIF图片将存在的路径. 例如: 第一个参 ...
- Java图片合成并引入外部字体写入文字
业务需要将两个图片合成,并按指定字体写入标语以及用户的经纬度,代码如下: import cn.hutool.core.img.GraphicsUtil;import javax.imageio.Ima ...
- JAVA实现基于ZXing的二维码自动生成与图片合成
JAVA实现基于ZXing的二维码自动生成与图片合成 近日做项目需要生成带有信息的二维码,并嵌入到一张图片中.实现思路采用Zxing生成二维码,java图形库进行图片的嵌入. 生成二维码 ZXing是 ...
最新文章
- geany配置python_Linux系统下搭建基于Geany+Python开发环境
- mysql 取 浮点运算_mysql 浮点型运算误差原因分析及解决方法
- PAT1010 一元多项式求导 (25 分)
- C#序列化与反序列化详解
- sco linux crontab重启,crontab 详解
- 利用Object.defineProperty实现Vue数据双向绑定
- 2080 Ti莫名起火,英伟达承认GPU有缺陷,财报后股价暴跌19%
- [小工具] 文本形式转储二进制
- java 人脸活体检测_人脸识别活体检测测试案例
- 手机号码、电子邮箱、身份证、银行卡正则验证
- HTML导出生成Word文档
- Linux内核版本和发行版本
- 我的QT Creator学习笔记(二十一)——Qt国际化和Qt插件
- audio: /dev/dsp: No such file or directory madplay
- 超全总结:Go 读文件的 10 种方法
- 《ACT 敏捷教练战术手册》正式发布:ACT 是什么?它和 Scrum 与 Kanban 有什么区别? ...
- 【存储】RAID 技术介绍和总结
- JS实现sleep,普通版+promise+async/await
- 提高电脑运行速度的方法(初级篇)
- 获取微信小程序源码并进行反编译
热门文章
- ros ubuntu 卸载_ROS的安装和卸载
- 深势科技创始人首席科学家张林峰:AI+分子模拟,赋能药物发现新源头
- 7个小故事,或许能给你些启发
- GitHub开发者自研火星车,开源
- IE浏览器消失了?这个软件即可恢复IE浏览器
- android实现mysql数据库存储_一个简单的Android端对象代理数据库系统的实现(二、执行+存储)...
- 墨者靶场--手工注入mysql数据库
- 【陈寿福案】珊瑚虫QQ侵权案民事判决书
- Marco's Java【小工具篇 之 Google Zxing 二维码生成】
- NI labview2014/2015/2016的超快速入门教程之使用VI模板(培训一)