(DataBufferUShort).getData()的内容

时间:2014-06-07 09:48:15

标签: java awt png bufferedimage

如果short[]bufferedImage.getRaster().dataBuffer.getData()的实例,我无法理解如何从dataBuffer获取DataBufferUShort的RGBA值。

如何将这些值(甚至可以是-30000)转换为0..255?如果dataBufferDataBufferByte的实例,我可以简单地做出这样的事情:

result[i] = (array[i] < 0) ?
     array[i] + 256 :
     array[i];

但我应该如何处理DataBufferUShort?某些PNG图片具有此类型,而不是期待DataBufferByte

getType()返回TYPE_CUSTOM。这是图像:http://i.stack.imgur.com/YwmkO.png

1 个答案:

答案 0 :(得分:1)

DataBufferUShort可以容纳多种类型的样本,因此您首先需要确定您拥有的数据。以下是最常见的:

如果图像数据代表16位灰度样本,则需要将所有值向下缩放以获得8位灰度值。您可以通过将值向右移动8位来实现。

DataBufferUShort dataBuffer;
short[] data = dataBuffer.getData();

byte[] gray = new byte[data.length];

for (int i = 0; i < data.length; i++) {
    gray[i] = (byte) ((data[i] & 0xff00) >> 8);
}

如果图像数据表示每个采样16位(A)RGB值,您可以执行与上面相同的操作,您将只有3个(或者如果有阿尔法的4个)样本或每个像素的数组元素而不是一个。

如果数据表示每个样本ARGB为16位(您的样本似乎就是这种情况),您还可以转换为int打包的ARGB样本,如下所示:

DataBufferUShort dataBuffer;
short[] data = dataBuffer.getData();

int[] argb = new byte[data.length / 4];

for (int i = 0; i < data.length; += 4) {
    int a = (data[i    ] & 0xff00) >> 8;
    int r = (data[i + 1] & 0xff00) >> 8;
    int g = (data[i + 2] & 0xff00) >> 8;
    int b = (data[i + 3] & 0xff00) >> 8;

    argb[i / 4] = a << 24 | r << 16 | g << 8 | b;
}

如果图像数据代表15/16位RGB(如TYPE_USHORT_555_RGBTYPE_USHORT_565_RGB),则必须将RGB值缩放到完整的8位/样本范围。类似的东西:

DataBufferUShort dataBuffer;
short[] data = dataBuffer.getData();

byte[] rgb = new byte[data.length * 3];

for (int i = 0; i < data.length; i++) {
    int shortRGB = data[i] & 0xffff;

    // Assuming 5 bit R, 5 bit G, 5 bit B, using the lower 15 bits
    rgb[i * 3 + 0] = ((((shortRGB & 0x7C00) >> 10) + 1) * 8) - 1;
    rgb[i * 3 + 1] = ((((shortRGB & 0x03E0) >>  5) + 1) * 8) - 1;
    rgb[i * 3 + 2] = ((((shortRGB & 0x001F)      ) + 1) * 8) - 1;
}

对于565 RGB甚至4444 ARGB(在某些Android设备中使用),程序非常相似。