Java 在SWT画布上绘制AWT BuffereImage
我正在尝试编写一个SWT组件,它能够获取并绘制Java 在SWT画布上绘制AWT BuffereImage,java,swt,awt,Java,Swt,Awt,我正在尝试编写一个SWT组件,它能够获取并绘制java.awt.buffereImage的实例。我的问题是SWT的Image和AWT的buffereImage不兼容:SWT组件不能绘制java.AWT.Image,AWT/Swing组件不能绘制org.eclipse.SWT.graphics.Image 有几种方法试图以其他方式解决此问题(也可能有一些变化,但基本上有以下两种): 他们都有缺点,不能满足我的期望: 第一种方法是将SWT图像转换为缓冲图像,由于为每个像素创建了一个新的RGB实例
java.awt.buffereImage
的实例。我的问题是SWT的Image
和AWT的buffereImage
不兼容:SWT组件不能绘制java.AWT.Image
,AWT/Swing组件不能绘制org.eclipse.SWT.graphics.Image
有几种方法试图以其他方式解决此问题(也可能有一些变化,但基本上有以下两种):
他们都有缺点,不能满足我的期望:
图像
转换为缓冲图像
,由于为每个像素创建了一个新的RGB
实例,因此导致大图像的性能较差org.eclipse.swt.widgets.Canvas
或org.eclipse.swt.widgets.Composite
),它允许直接绘制缓冲图像
)
我的方法是逐像素绘制。因此,我只需要获得一个GC
的实例,从左到右逐行遍历源buffereImage
并使用GC.setForeground(Color Color)
和GC.drawPoint(intx,inty)
绘制相应的Color
首先,我为每个像素创建了一个新的Color
实例,它使用了大量内存并增加了额外的延迟,因为newcolor
需要系统资源,为每个像素创建一个新对象也需要时间
然后,在绘制图像之前,我尝试将所有可能的(24位)Color
s预加载到一个数组中。这导致了内存使用量的激增(>=600MB),在我尝试之前这是很清楚的,但我必须验证它
仅缓存使用过的颜色也会导致比需要更多的内存消耗
我认为必须有一种更低级的方法,它不需要那么多内存,因为SWT能够在不消耗那么多内存的情况下绘制整个(SWT)Image
s
如果有任何想法或解决方案,我将不胜感激。我发现有一种方法可以通过使用原始图像的数据缓冲区(如果是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);
可能其他位深度也可以用类似的方式进行转换,但这就是我目前所需要的。您在第一篇参考资料中描述的使用RGB的方法看起来要快得多-您真的尝试过吗?我想有这样一种方法。然而,AWT和SWT都依赖本机代码来实现底层图形。因此,您的低级桥接很可能涉及一些在AWT和SWT案例中使用的本机数据结构上操作的粗糙本机代码。这些代码需要在多个硬件和操作系统平台上实现。不漂亮。@greg-449是的,但我对每个像素的新RGB
调用不满意。这确实比我自己的方法快得多。@StephenC可能是的。但是也许有人知道一个更好的方法。只是好奇,但是为什么不直接用SWT加载图像呢?是否有理由使用Swing/AWT的迂回功能?我从使用的另一个库中获取图像,并希望解决保存图像的麻烦—创建一个临时文件,然后使用SWT重新加载它。这将花费额外的不必要的时间。我以这种方式修改了您的代码以处理单色图像:RGB[]colors=new RGB[]{new RGB(0,0,0),new RGB(255255)};PaletteData调色板=新PaletteData(颜色);ImageData data=新的ImageData(original.getWidth()、original.getHeight()、1、调色板、4、((DataBufferByte)original.getData().getDataBuffer()).getData());