Tre*_*vor 7 javascript image-processing webgl
我正在尝试从服务器下载16位图像数据并将其推送到没有浏览器插件的WebGL纹理.texImage2d将使用:ImageData,HTMLImageElement,HTMLCanvasElement或HTMLVideoElement.我正在寻找一些javascript(一个库或代码示例),它可以将16位TIFF或类似的(hdf5等)图像数据解码为这些对象类型之一.
我没有问题,这是每通道8位RGB通过使用加载PNG但这不适用于每通道16位数据,因为没有任何"标准"浏览器支持的图像格式是16-位.
如果合并两个 PNG 图像,一个是前 8 位,第二个是低 8 位,我认为应该是:
highp vec4 texCol = texture2D(tex_low, vec2(vTexCoord.s, vTexCoord.t)) * (1.0 / 257.0);
texCol += texture2D(tex_up, vec2(vTexCoord.s, vTexCoord.t)) * (256.0 / 257.0);
Run Code Online (Sandbox Code Playgroud)
每通道 8 位的 RGB 颜色范围为 0 到 255 = 2^8 - 1。
每通道 16 位的 RGB 颜色范围为 0 到 65535 = 2^16 - 1 = 255*257。
WebGL 使用从 0 到 1 的颜色值,并通过将 8 位颜色值除以 255 来实现。因此,划分后的值属于 <0,1> 范围。
在每个通道 16 位的情况下,我们希望将其除以 65535 以从范围 <0,1> 中获得正确的数字。
我们想要的是减少到范围 <0,1> 的 16 位颜色值。
让low和up成为 0..255 范围内的颜色值。up是高 8 位,low低 8 位。
要得到16位的值,我们可以计算:low + up*256。现在我们的数字在 0..65535 范围内。为了从 <0,1> 范围获得值,我们将其除以 65535。请注意,WebGL 使用范围 <0,1> 的颜色值工作,它是Lw=low/255和Uw=up/255。因此,我们不必将其乘以 255 再除以 65535,因为 65535 = 255*257。相反,我们只是除以 257。

另外我找不到任何软件可以将 16 位/通道图像拆分为两个 8 位/通道图像,所以这是我的代码,请随意使用它,它将 16 位/通道 Tiff 拆分为两个 8 位/通道 PNG:
https://github.com/czero69/ImageSplitter
小智 5
PNGToy是一个非常有特色的库,用于使用 javascript 提取几乎所有深度和通道模式的 PNG 块(真正的客户端/没有 Node.js,只有 Promise.js 依赖项)。解码方法将返回所需的缓冲区。以下是 16 位灰度 PNG 的示例(16 位 RGB 也应该有效):
var dataObj;
var img = new PngImage();
var buffer;
img.onload = function() {
var pngtoy = this.pngtoy;
dataObj = pngtoy.decode().then(function(results) {
buffer = new Uint16Array(results.bitmap);
for(var i = 0, j; i < buffer.length; i++) {
j = buffer[i];
buffer[i] = ((j & 0xff) << 8) | ((j & 0xff00) >>> 8); // needed to swap bytes for correct unsigned integer values
}
console.log(buffer);
});
};
img.onerror = function(e) {
console.log(e.message);
};
img.src = "image.png";
Run Code Online (Sandbox Code Playgroud)
我认为目前主要浏览器本身不支持任何 16 位/通道图像格式。
实现相同效果的一种方法是创建两张 PNG 图像,一张包含图像中每个颜色通道的顶部 8 位,另一张包含底部 8 位。然后将图像绑定为两个纹理并组合着色器中的值,例如
highp float val = texture2d(samplerTop8bits, tex_coord) * (256.0 / 257.0);
val += texture2d(samplerBottom8bits, tex_coord) * (1.0 / 257.0);
Run Code Online (Sandbox Code Playgroud)
(注意:您需要高精度才能在 16 位范围内正确表示数据)
仅当您的目标浏览器支持浮点纹理时,才可以使用另一种方法。您可以在浏览器中将两个 PNG 图像组合成一个浮点纹理,然后正常访问它。这可能不会更快,并且可能会使用两倍的纹理内存。