如果short[]
是bufferedImage.getRaster().dataBuffer.getData()
的实例,我无法理解如何从dataBuffer
获取的DataBufferUShort
获取RGBA值。
如何将这些值(甚至可以是-30000)转换为0..255?如果dataBuffer
是DataBufferByte
的实例,我可以简单地进行如下操作:
result[i] = (array[i] < 0) ?
array[i] + 256 :
array[i];
但是
DataBufferUShort
我该怎么办?一些PNG图像具有这种类型,而不是期望DataBufferByte
。getType()返回TYPE_CUSTOM。这是图像:http://i.stack.imgur.com/YwmkO.png
最佳答案
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);
}
如果图像数据表示每个样本(A)RGB值16位,则可以执行与上述相同的操作,则每个像素只有3个(或4个,如果有alpha)样本或数组元素,而不是一个。
如果数据代表每个样本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_RGB
或TYPE_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设备中使用),过程非常相似。