希望在Javascript / WebGL中访问16位图像数据

时间:2011-06-20 15:34:38

标签: javascript image-processing webgl

我正在尝试从服务器下载16位图像数据,并将其推送到没有浏览器插件的WebGL纹理中。 texImage2d将使用:ImageData,HTMLImageElement,HTMLCanvasElement或HTMLVideoElement。我正在寻找一些javascript(一个库或代码示例),它可以将16位TIFF或类似的(hdf5等)图像数据解码为其中一种对象类型。

通过使用加载PNG,这样做每通道8位RGB是没有问题的,但这不适用于每通道16位数据,因为没有任何“标准”浏览器支持的图像格式是16位。

3 个答案:

答案 0 :(得分:4)

我认为主浏览器目前不支持任何16位/通道图像格式。

实现相同效果的一种方法是创建两个PNG图像,一个具有图像中每个颜色通道的前8位,另一个具有底部8位。 然后将图像绑定为两个纹理并组合着色器中的值,例如

highp float val = texture2d(samplerTop8bits, tex_coord) * (256.0 / 257.0);
val += texture2d(samplerBottom8bits, tex_coord) * (1.0 / 257.0);

(注意:您需要高精度才能在16位范围内正确表示数据)

只有在目标浏览器中支持浮点纹理时,才能使用另一种方法。您可以在浏览器中将两个PNG图像组合成浮点纹理,然后正常访问。这可能不会更快,并且可能会使用两倍的纹理内存量。

答案 1 :(得分:4)

如果组合两个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);

每通道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>获得正确的数字。

我们想要的是16位颜色值减小到范围&lt; 0,1&gt; 让lowup为范围0..255的颜色值。 up是前8位,low是低8位 要获得16位值,我们可以计算:low + up*256。现在我们的数字在0..65535范围内。从范围&lt; 0,1&gt;获得值我们将它除以65535.注意,WebGL使用范围&lt; 0,1&gt;的颜色值工作。 ,它是Lw=low/255Uw=up/255。因此,我们不必将它乘以255并将其除以65535,因为65535 = 255 * 257。相反,我们只是除以257。

enter image description here

另外我找不到任何软件将16位/通道图像分成两个8位/通道图像,所以这是我的代码,随意使用它,它将16位/通道Tiff分成两个8位/通道PNG格式:

https://github.com/czero69/ImageSplitter

答案 2 :(得分:2)

PNGToy是一个非常有特色的库,用于使用javascript(实际上是客户端/没有node.js,只是Promise.js依赖项)提取几乎所有深度和通道模式的PNG块。 decode方法将返回所需的缓冲区。以下是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";