Java 在SWT画布上绘制AWT BuffereImage

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实例

我正在尝试编写一个SWT组件,它能够获取并绘制
java.awt.buffereImage
的实例。我的问题是SWT的
Image
和AWT的
buffereImage
不兼容:SWT组件不能绘制
java.AWT.Image
,AWT/Swing组件不能绘制
org.eclipse.SWT.graphics.Image

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

  • 他们都有缺点,不能满足我的期望:

  • 第一种方法是将SWT
    图像
    转换为
    缓冲图像
    ,由于为每个像素创建了一个新的
    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());