【问题标题】:Content of (DataBufferUShort).getData()(DataBufferUShort).getData() 的内容
【发布时间】:2014-07-28 13:20:20
【问题描述】:

如果dataBufferDataBufferUShort 的实例,我无法理解如何从bufferedImage.getRaster().dataBuffer.getData() 获得的short[] 获取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

【问题讨论】:

  • 我们说的是 16 位/样本灰色,还是 5/5/5 或 5/6/5 位/样本 RGB?
  • data.length 确实是 w * h * 4,因此您可以像下面我的第一个示例那样将数据转换为具有 byte[] argb 样本。
  • 更新了答案以获取int ARGB 样本。

标签: java awt png bufferedimage


【解决方案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 个,如果有 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_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 设备中使用),过程非常相似。

【讨论】:

  • 数据数组包含 3*widthheight 元素而不是 widthheight。此外,图像包含 alpha 通道,所以我无法理解为什么每个像素有三个项目。
  • @Vladiator Strange...也许你可以链接图像文件?另外,在您的问题中添加BufferedImage 输入图像是什么?
  • 有一个奇怪的图像类型。我已经编辑了问题。
猜你喜欢
  • 2015-01-05
  • 1970-01-01
  • 2020-01-22
  • 1970-01-01
  • 2020-07-31
  • 2023-01-07
  • 2013-10-06
  • 2019-05-15
  • 2021-08-07
相关资源
最近更新 更多