我正在尝试编写一个SWT组件,该组件能够获取和绘制的实例java.awt.BufferedImage
。我的问题是SWTImage
和AWTBufferedImage
不兼容:SWT组件无法绘制java.awt.Image
,AWT / Swing组件无法绘制org.eclipse.swt.graphics.Image
。
有几种方法可以尝试以其他方式解决此问题(也可能会有一些变化,但是基本上有这两种):
他们都有缺点,没有满足我的期望:
Image
为BufferedImage
,由于RGB
为每个Pixel创建一个新实例,导致大图像的性能较差。由此得出的结论是,我将尽力编写一个组件(基于org.eclipse.swt.widgets.Canvas
或org.eclipse.swt.widgets.Composite
),该组件允许BufferedImage
直接绘制图像而无需任何图像转换。
我的方法是逐像素绘制它。因此,我只需要获取一个实例GC
,BufferedImage
一行一行地从左到右移动源代码,并Color
使用GC.setForeground(Color color)
和绘制相应的内容GC.drawPoint(int x, int y)
。
首先,我Color
为每个像素创建了一个新实例,该实例占用了大量内存并增加了额外的延迟,因为这需要new Color
获取系统资源,并且为每个像素创建一个新对象也需要花费时间。
然后,我尝试Color
在绘制图像之前将所有可能的(24位)预加载到数组中。这导致内存使用量激增(> = 600 MB),这在我尝试之前很明显,但是我必须对其进行验证。
仅缓存使用过的颜色也会导致比所需更多的内存消耗。
我认为必须有一种不需要太多内存的低层方法,因为SWT可以绘制整个(SWT)Image
而不消耗太多内存。
我将不胜感激任何想法或解决方案。
我发现有一种方法“转换”的BufferedImage
一个Image
使用,如果它是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);
可能其他比特深度也可以类似的方式转换,但这只是我目前需要的。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句