图 1. 屏外图像技术允许在 SWT 上使用 Java 2D
图 1 中显示的屏外 AWT 图像被初始化为透明背景。然后对屏外图像的图形上下文调用 Java 2D 方法。像所有 AWT 图像一样,屏外图像的图形上下文自动支持 Java 2D。完成了所有特定于 Java 2D 的绘制后,提取 AWT 图像的像素值并传送到一个屏外 SWT 图像中。然后用工具箱的 GC.drawImage(...) 方法在 SWT 组件上绘制这个 SWT 图像,就像所有正常图像一样。
我将在下面几节中完成这个过程中的每一步。
创建 AWT 屏外图像
对于 AWT 屏外图像,要使用 java.awt.image.BufferedImage 实例。BufferedImage 是一个可以通过它的 API 访问其像素数据的图像。访问到了图像的像素值就可以在以后将它转换为 SWT 图像。
构建一个 AWT 缓冲图像的最简单方法是使用构造函数 public BufferedImage(int width, int height, int imageType)。前两个参数表明图像具有的大小。第三个参数是指定要创建的图像 类型 的常量。图像类型 可能的值是在类 BufferedImage 中声明的常量 TYPE_XXX 之一 表明像素值是如何存储在图像中的。在彩色图像中一般使用以下几种最重要的图像类型:
TYPE_BYTE_INDEXED:这种图像类型的图像将使用一个索引颜色模型。索引颜色模型的意思是图像中使用的每一种颜色都是在一组颜色中索引的。像素值只包含这个像素的颜色在颜色模型中的索引。这种类型的图像局限于 256 种颜色 也就是颜色模型的大小。以这种方式存储像素信息可以很紧凑地表示图像,因为每一个像素都只用一个字节编码。
TYPE_INT_RGB:
这种类型常量表明图像使用直接颜色模型。直接颜色模型 的意思是每一个像素的值包含关于其颜色的完整信息。TYPE_INT_RGB 表明每一个像素都是用一个整数(四字节)编码的。每一个像素中编码的信息是这个像素所使用的颜色的红、绿和蓝(RGB)成分。每一种颜色成分都用一个字节编码。因为整个像素值是用四个字节编码的,所以有一个字节是未使用的。这种图像的内部表示占用的内存是使用索引颜色模型的图像的四倍,但是这种图像可以使用的颜色数增加到了 1 百 60 万(256 x 256 x 256)。
TYPE_INT_ARGB:
与 TYPE_INT_RGB 一样,这种类型的图像使用直接颜色模型并用四个字节编码每一个像素。不同之处在于,这里用 TYPE_INT_RGB 没有使用的第四个字节表示像素的透明度,有时也称为颜色的 alpha 成分。这种类型的图像可以有透明的背景,也可以是半透明的。 为了让屏外图像技术可以工作,需要只将受到 Java 2D 绘制影响的像素传送到 SWT 组件的表面。为了保证这一点,初始图像必须有透明背景。因此,对于 AWT 屏外图像,使用的缓冲图像类型为 TYPE_INT_ARGB。
(本文来源于图老师网站,更多请访问http://m.tulaoshi.com/bianchengyuyan/)绘制和提取图像
这个过程的下一步是用 Java 2D 绘制图像。首先取得它的 Graphics2D 上下文。可以用方法 createGraphics2D() 或者调用 getGraphics() 做到这一点。在这个上下文上绘制将会自动修改图像的像素数据。在绘制完成后,可以用方法 getRGB(int startX, int startY, int w, int h, int rgbArray, int offset, int scansize) 容易且高效地提取图像的像素值。这个方法可以将图像中矩形区域的像素数据传输到一个整数数组中。getRGB() 方法的参数如下:
startX, startY 是要提取的区域左上角图像的坐标
(本文来源于图老师网站,更多请访问http://m.tulaoshi.com/bianchengyuyan/)w, h 是要提取的区域的宽度和高度
rgbArray 是接收像素值的整数数组
offset 是数组中接收第一个像素值的位置的索引。
scansize 是图像中相邻两行中具有相同行索引的像素的索引偏移值。如果这个值与要提取的区域的宽度相同,那么一行的第一个像素就会存储在数组中前一行最后一个像素后面的索引位置。如果这个值大于提取区域的宽度,那么数组中,在一行最后和下一行开始之间就会有一些未使用的索引。
存储像素数据
图 2 显示 BufferedImage.getRGB(...) 如何在提取了 AWT 图像的矩形区域后填充整数缓冲区。图中下面的部分表示整数缓冲区。每一个框表示缓冲区中包含一个像素 4 字节 ARBG 值的一个值。括号中的数字表示像素在图像中的坐标。
图 2. 从 AWT 图像中提取像素值 在这种情况下,不使用任何 offset,这意味着第一个像素将保存在缓冲区索引 0 的位置。scansize 的值取要提取的区域的宽度,这意味着提取的一行中的第一个像素会接着前一行的最后一个像素的缓冲区位置。使用这些参数,整数的缓冲区就一定会足够大,可以包含 w*h 个整数。当每一个像素的颜色信息都存储到了一个整数的简单缓冲区后,就可以将这些信息传输到 SWT 屏外图像中。