最近写了一个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();

这个代码可以合成图片,但是有两个问题

  1. 图片失真
  2. 图片合成后在叠加的部分颜色发生了变化

第三个版本

使用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 处理图片图片合成相关推荐

  1. JAVA操作图片/合成/电子盖章等

    JAVA操作图片/合成/电子盖章等 /**** @param mainFile* @param file1* @param f 透明度 最大为1* @param response* @return* ...

  2. Java 实现图片合成

    2019独角兽企业重金招聘Python工程师标准>>> 图片合成 利用Java的绘图方法,实现图片合成 在开始之前,先定一个小目标,我们希望通过图片合成的方式,创建一个类似下面样式的 ...

  3. java进行图片合成以及写入自定义字体

    由于工作需要做了一个利用java的Graphics2D进行图片合成且在图片上写入自定义字体文字的小功能, 那就顺便记录一些痕迹,有什么不好的地方请见谅 public static void main( ...

  4. linux centos java kumo图片合成文字 词云插件 字体乱码问题

    linux下安装微软雅黑字体库 或者其他字体 jieba 词云 kumo相关 百度随便找个ttf安装就行 用winscp直接切目录 /usr/share/fonts/ 放入*.ttf字体文件 先看看f ...

  5. Java实现图片合成

    功能 竖向合成多张大小不一致的图片,以最宽图片的为宽为合成后的宽度, 高为所有图片的总高度.图片宽度没有达到合成的宽度则填充部分使用白色画布填充. 代码 /*** 多张图片进行竖向合并成一张图片* @ ...

  6. java实现图片合成gif图——输出到具体路径或流数据上传

    一.多图片转gif 转存到输出流 /*** 多图片转gif 转存到输出流** @param imageList* @param os* @throws IOException*/private sta ...

  7. JAVA 由图片合成gif文件

    1.需要四个类,直接应用到项目中,不需要做太多改动,除了导包: 2.jpgToGif函数需要传入两个参数,第一个参数为要合成的图片路径数组,第二个参数为合成的GIF图片将存在的路径. 例如: 第一个参 ...

  8. Java图片合成并引入外部字体写入文字

    业务需要将两个图片合成,并按指定字体写入标语以及用户的经纬度,代码如下: import cn.hutool.core.img.GraphicsUtil;import javax.imageio.Ima ...

  9. JAVA实现基于ZXing的二维码自动生成与图片合成

    JAVA实现基于ZXing的二维码自动生成与图片合成 近日做项目需要生成带有信息的二维码,并嵌入到一张图片中.实现思路采用Zxing生成二维码,java图形库进行图片的嵌入. 生成二维码 ZXing是 ...

最新文章

  1. geany配置python_Linux系统下搭建基于Geany+Python开发环境
  2. mysql 取 浮点运算_mysql 浮点型运算误差原因分析及解决方法
  3. PAT1010 一元多项式求导 (25 分)
  4. C#序列化与反序列化详解
  5. sco linux crontab重启,crontab 详解
  6. 利用Object.defineProperty实现Vue数据双向绑定
  7. 2080 Ti莫名起火,英伟达承认GPU有缺陷,财报后股价暴跌19%
  8. [小工具] 文本形式转储二进制
  9. java 人脸活体检测_人脸识别活体检测测试案例
  10. 手机号码、电子邮箱、身份证、银行卡正则验证
  11. HTML导出生成Word文档
  12. Linux内核版本和发行版本
  13. 我的QT Creator学习笔记(二十一)——Qt国际化和Qt插件
  14. audio: /dev/dsp: No such file or directory madplay
  15. 超全总结:Go 读文件的 10 种方法
  16. 《ACT 敏捷教练战术手册》正式发布:ACT 是什么?它和 Scrum 与 Kanban 有什么区别? ...
  17. 【存储】RAID 技术介绍和总结
  18. JS实现sleep,普通版+promise+async/await
  19. 提高电脑运行速度的方法(初级篇)
  20. 获取微信小程序源码并进行反编译

热门文章

  1. ros ubuntu 卸载_ROS的安装和卸载
  2. 深势科技创始人首席科学家张林峰:AI+分子模拟,赋能药物发现新源头
  3. 7个小故事,或许能给你些启发
  4. GitHub开发者自研火星车,开源
  5. IE浏览器消失了?这个软件即可恢复IE浏览器
  6. android实现mysql数据库存储_一个简单的Android端对象代理数据库系统的实现(二、执行+存储)...
  7. 墨者靶场--手工注入mysql数据库
  8. 【陈寿福案】珊瑚虫QQ侵权案民事判决书
  9. Marco's Java【小工具篇 之 Google Zxing 二维码生成】
  10. NI labview2014/2015/2016的超快速入门教程之使用VI模板(培训一)