使用JavaScript如何解码JPEG2000位数组图像

11

我正在使用文件 API来解析 DICOM 文件并将其数据存储为字节数组。

问题在于,我无法解码 JPEG2000 图像并在浏览器(Chrome、Firefox 等)中显示它。例如,如果图像数据以 JPEG 格式编码,那么在浏览器中显示图像就没有问题,但问题出现在 JPEG2000 或 JPEG-LS 上。

我知道这些图像格式默认情况下无法在 Web 浏览器中显示,但肯定有一种方法可以在 JavaScript 中解码 JPEG2000 或 JPEG-LS 图像数据,对吗?


这个 https://www.npmjs.com/package/jpeg2000 应该有助于基于 Mozilla 的 PDF.js 源代码的码流处理。 - deadrunk
这个https://www.npmjs.com/package/jpeg2000应该对基于Mozilla的PDF.js源代码的码流有所帮助。 - deadrunk
2个回答

17

由于JPEG 2000图像不能在浏览器中原生呈现,因此您可能需要在将它们用于网页之前将它们转换为浏览器可以呈现的格式。最简单的方法是在服务器端将图像转换为一些Web安全格式,然后将转换后的图像提供给浏览器使用。但是,如果您决定在客户端处理,则可以在此处找到使用JavaScript解码JPEG 2000图像的示例:https://github.com/kripken/j2k.js/blob/master/examples/simple.html

这个示例使用OpenJPEG库的JavaScript编译版本,在此可用。虽然这是自动转换,不太易用,但他们提供了以下函数,使其使用变得更容易:

// Wrapper around OpenJPEG..
//Converts the given j2k image array to RGB values that
//can be put into a Canvas..
function j2k_to_image(data) {
    run();
    _STDIO.prepare('image.j2k', data);
    callMain(['-i', 'image.j2k', '-o', 'image.raw']);
    return _STDIO.streams[_STDIO.filenames['image.raw']].data;
}

这里期望的 data 是一个JavaScript字节数组(值介于0到255之间的JavaScript数字),就像示例文件中所示。你可以通过在服务器端将图像转换为此形式来获得它,或者使用Ajax将它们加载并将响应视为二进制数据 (请参见MDN使用XHR中如何在Firefox中执行此操作,其他浏览器可能需要不同的方法)。然后将此函数的输出放入Canvas元素中,如下所示:

  output = j2k_to_image([255, 0, 123, ...]); //pass in the JPEG 2000 image as an array

  var canvas = document.getElementById('canvas'); //get the canvas element (use whatever you actually need here!)
  canvas.width = imageWidth;
  canvas.height = imageHeight;

  var ctx = canvas.getContext('2d');
  var image = ctx.getImageData(0, 0, canvas.width, canvas.height);

  var componentSize = canvas.width*canvas.height;
  for (var y = 0; y < canvas.height; y++) {
    for (var x = 0; x < canvas.width; x++) {
      var value = output[y*canvas.width + x];
      var base = (y*canvas.width + x)*4;
      image.data[base + 0] = output[0*componentSize + y*canvas.width + x];
      image.data[base + 1] = output[1*componentSize + y*canvas.width + x];
      image.data[base + 2] = output[2*componentSize + y*canvas.width + x];
      image.data[base + 3] = 255; //the alpha part..
    }
  }
  ctx.putImageData(image, 0, 0);

由于这使用了Canvas元素,所以这在IE8中无法工作,但是针对这个问题可能可以做一些其他的东西。例如,您可以尝试以位图或其他简单的IE兼容格式获取转换后的图像数据,将其进行base64编码,然后将其放入图像元素的源中,具体请参见http://css-tricks.com/data-uris/,其中有关于如何使用数据URL的示例。


非常感谢!我已经尝试了那个JavaScript库(J2K.js),它完美地工作了!问题只出现在大小小于1MB的图像上,如果大小更大,则无法正常工作。因为我们正在使用DICOM图像(5 MB大小的J2K),所以对我们来说效果不佳。但我会尝试使用AJAX。再次感谢。 - user1211709
请注意 j2k.js 库的 URL 已更改。我已编辑了答案,但我怀疑还有工作要做。 - Ori Pessach

7
我相信pdf.js项目可以解码PDF文件中压缩的JPEG2000图像。请参见该项目的stream.js文件中的此代码评论部分此推文

感谢@notmasteryet在不到一个月的时间里编写了一个仅有2000行的js jpx解码器,我们现在支持JPEG 2000图像。

- 2012年1月20日 下午2:36


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接