【发布时间】:2014-08-06 02:13:48
【问题描述】:
我正在尝试编写一个 SWT 组件,它能够获取和绘制java.awt.BufferedImage 的实例。我的问题是SWT的Image和AWT的BufferedImage不兼容:SWT组件不能画java.awt.Image,AWT/Swing组件不能画org.eclipse.swt.graphics.Image。
有几种方法试图以其他方式解决这个问题(也可能有一些变化,但基本上有这两种):
他们都有缺点,没有达到我的期望:
- 第一种方法是将 SWT
Image转换为BufferedImage,由于为每个像素创建一个新的RGB实例,导致大图像的性能不佳。 - 第二种方法在可用性方面有几个缺点。请参阅链接文章末尾的“解决方法”。
由此得出的结论是,我会尽力编写一个组件(基于org.eclipse.swt.widgets.Canvas 或org.eclipse.swt.widgets.Composite),它允许直接绘制BufferedImage 而无需任何图像转换。
我的方法是逐个像素地绘制它。因此,我只需要获取GC 的实例,从左到右逐行遍历源BufferedImage,并使用GC.setForeground(Color color) 和GC.drawPoint(int x, int y) 绘制相应的Color。
首先,我为每个像素创建了一个Color 的新实例,它使用了大量内存并增加了额外的延迟,因为new Color 获取系统资源并为每个像素创建一个新对象也需要时间.
然后我尝试在绘制图像之前将所有可能的(24 位)Colors 预加载到一个数组中。这导致内存使用量激增 (>= 600 MB),这在我尝试之前很清楚,但我必须验证它。
只缓存使用过的颜色也会导致比原本需要的更多的内存消耗。
我认为必须有一种不需要那么多内存的更底层的方法,因为 SWT 能够在不消耗那么多内存的情况下绘制整个 (SWT) Images。
如果有任何想法或解决方案,我将不胜感激。
【问题讨论】:
-
第一个参考文献中描述的使用 RGB 的方法看起来会快很多 - 你真的尝试过吗?
-
我想有这样的方法。但是,AWT 和 SWT 都依赖本机代码来实现低级图形。因此,您的低级桥接很可能涉及一些在 AWT 和 SWT 案例中使用的本机数据结构上运行的粗糙本机代码。这将需要跨多个硬件和操作系统平台实现代码。不漂亮。
-
@greg-449 是的,但我对每个像素的
new RGB调用并不满意。这确实比我自己的方法快得多。 -
@StephenC 可能是的。但也许有人知道更好的方法。