当前位置: 首页 > 知识库问答 >
问题:

在SWT画布上绘制AWT BuffereImage

韩经武
2023-03-14

我试图编写一个SWT组件,它能够采取和绘制java.awt.BufferedImage的实例。我的问题是SWT的Image和AWT的BufferedImage不兼容:SWT组件不能绘制java.awt.Image,AWT/Swing组件不能绘制org.eclipse.swt.graphics.Image

有几种方法试图以其他方式解决这个问题(也可能有一些变化,但基本上有以下两种):

  1. 在SWT图像和AWT BuffereImage之间转换

他们都有缺点,没有满足我的期望:

  1. 第一种方法是将SWT图像转换为缓冲图像,由于为每个像素创建了一个新的RGB实例,因此对大图像的性能较差
  2. 第二种方法在可用性方面有几个缺点。请参阅链接文章末尾的“变通方法”

这导致我的结论是,我会尽最大努力编写一个组件(基于org.eclipse.swt.widgets.Canvasorg.eclipse.swt.widgets.Composite),它允许直接绘制缓冲图像)。

我的方法是逐像素绘制。因此,我只需要获得一个GC的实例,从左到右逐行遍历源buffereImage,并使用GC绘制相应的Color。设置前景(颜色)GC。绘图点(整数x,整数y)

首先,我为每个像素创建了一个新的Color实例,这会占用大量内存并增加额外的延迟,因为new Color需要系统资源,为每个像素创建一个新对象也需要时间。

然后,在绘制图像之前,我尝试将所有可能的(24位)Colors预加载到一个数组中。这会导致内存使用量激增(

只缓存使用过的颜色也会导致比需要更多的内存消耗。

我认为必须有一种更低级的方法,它不需要那么多内存,因为SWT能够在不消耗那么多内存的情况下绘制整个(SWT)Images。

如果有任何想法或解决方案,我将不胜感激。

共有1个答案

时仰岳
2023-03-14

我发现有一种方法可以通过使用原始图像的数据缓冲区(如果是24位RGB)将缓冲图像转换为图像。这是可能的,因为图像格式是兼容的。

final BufferedImage original = ImageIO.read(new File("some-image.jpg");

final PaletteData palette =
        new PaletteData(0x0000FF, 0x00FF00, 0xFF0000);

// the last argument contains the byte[] with the image data
final ImageData data = new ImageData(original.getWidth(), original.getHeight(),
        24, palette, 4,
        ((DataBufferByte) original.getData().getDataBuffer()).getData());

final Image converted = new Image(getDevice(), data);

这样,你就不必创建成千上万的新对象。这种方法的缺点是需要确保原始图像是RGB 24位类型。否则,图像必须转换为这种格式。

之后,可以使用以下代码绘制图像:

// get the GC of your component
gc.drawImage(image, 0, 0);

可能其他位深度可以以类似的方式转换,但这是我目前所需要的。

 类似资料:
  • 我想在画布上画一段视频。为了实现这一点,我在Javascript中捕获onMouseDown和onMouseUp事件,以获得每个事件的x和y坐标(我需要在画布中设置视频的位置、宽度和高度)。 因此,每次我在画布上绘制视频时,我创建的上一个视频都应该停止,并且必须播放新的视频。两个问题: 1)视频不播放(功能只画第一帧),但他的音频可以 2) 如何停止以前绘制的视频? 演示:http://jsfid

  • 我编写了这段代码,可以在JavaFX画布上绘制。它可以很好地工作,但我不知道如何重新绘制画布(比如在Swing中),以便在新画布上重新开始绘制。这是我的代码,非常感谢你的帮助!马里奥

  • 问题内容: 是否有将SVG文件绘制到HTML5画布上的默认方法?GoogleChrome支持将SVG加载为图像(并简单地使用),但是开发者控制台会对此进行警告。 我知道将SVG转换为canvas命令的可能性,但是我希望这不是必需的。我不在乎较旧的浏览器(因此,如果FireFox 4和IE 9支持某些功能,那就足够了)。 问题答案: 编辑2019年12月16日 现在所有主要浏览器都支持Path2D

  • 我目前正在使用画布开发一个JavaFX-Drawing-Application。在GraphicsContext的帮助下,我使用beginPath()和lineTo()方法绘制线条,但我无法找到实现橡皮擦的适当方法。

  • 5.2.3 在画布上绘图 本节介绍如何在画布上绘制图形。为了完整起见,我们将前面介绍过的首先需要执行的 几条语句合在一起复制如下: >>> from Tkinter import * >>> root = Tk() >>> c = Canvas(root,width=300,height=200,bg='white') >>> c.pack() 如前所述,c 是一个画布对象,而画布对象提供了若干