【问题标题】:Javascript Unsigned Short Grayscale ImagesJavascript 无符号短灰度图像
【发布时间】:2015-02-27 16:14:37
【问题描述】:

我正在将类型为 TYPE_USHORT_GRAY 的 Java BufferedImage 编码为 base64,通过 REST api 将其提供给 Javascript 客户端。

我可以在服务器端清楚地检查适当范围(0 到 65k)内的不同像素值,但 canvas api 似乎只提供 rgba 像素,导致我的用例的精度损失不可接受。

客户端 Javascript 是否可以通过画布或其他 api 读取和操作(但不显示)无符号短灰度图像的像素值?

【问题讨论】:

  • 您希望能够在画布中显示 16 位灰度图像?
  • 我希望能够读取适当范围内的灰度值,因为在我们的例子中,它们将根据这些值转换为不同的实际配色方案,然后显示。我会看看我是否可以在我的问题中澄清这一点。
  • 在发送到画布之前,您可能会更幸运地存储数据in a Int16Array 进行处理。
  • 哦,太好了,谢谢!我会对此进行调查并报告。
  • 我应该说使用UInt16Array 来处理无符号值。

标签: javascript canvas bufferedimage


【解决方案1】:

是的,您可以将像素存储在Uint16Array 缓冲区中,然后从中读取亮度值并将其写入其中。请注意,字节顺序(网络/大端与小端)很重要 - DataView 可以帮助您,或者如果传入缓冲区是大端,则只需交换字节顺序。

还要注意,超出范围的值会得到模处理,因此您需要手动剪辑它们(或使用掩码 0xffff 写入)。然后使用索引将每个亮度值作为普通数组访问。

但是,如果您打算进行大量处理,我建议您使用浮点缓冲区而不是标准化值,使用 Float32ArrayFloat64Array - 前者更快,后者更准确。这也将允许您根据需要将动态范围推入和推出,除非您需要钳制每个通道的值。

规范化(很明显,但为了记录):

newLum = oldLum / 0xffff;

提示:要获得更准确的预览,如果您在此过程中需要,请使用以下方法进行缩小 - 原则上适用于任何深度:

var inDepth = Math.pow(2, 16) - 1;   // 65535
var outDepth = Math.pow(2, 8) - 1;   // 255

那么对于每个亮度值:

var r,g,b,a;
r = g = b = (lum * outDepth / inDepth + 0.5)|0;    // or, in this case -
r = g = b = (lum * 0.0038910505836575876 + 0.5)|0;
a = 255;

如果源使用 gamma,则需要在处理之前将 gamma 转换为线性,完成后,重新应用 gamma。

你总是可以做一个掩码/移位操作。但这不会那么准确。

(Canvas 将始终使用基于 8 位的 RGBA 缓冲区)。

【讨论】:

    【解决方案2】:

    为了便于实施,我们决定将图像重新编码为一组 RGB 值,以捕获我们需要的全部值范围:基本上,将每个像素视为 3 位基数 256 数字。

    这种回避问题的方式,所以无论如何我都会接受 Ken Fyrstenberg 的回答。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-08-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-02-05
      • 1970-01-01
      相关资源
      最近更新 更多