How to decode a JPEG2000 bitarray image with JavaScript
Asked Answered
D

2

11

I'm using the File API to break down a DICOM file and get its data in a byte array.

The problem is that I can not decode a JPEG2000 image and show it in the browser (Chrome, Firefox, etc.). For example, if the image data is coded in JPEG format, I have no problem at all displaying the image in the browser, but the problem is with JPEG2000 or JPEG-LS.

I know that those image formats aren't able to show in the web browsers by default, but there must exist a way in JavaScript to decode the image data that is in JPEG2000 or JPEG-LS, surely?

Decree answered 15/2, 2012 at 15:51 Comment(1)
This npmjs.com/package/jpeg2000 should help with codestreams - based on Mozilla's PDF.js sourcecode.Romine
I
17

Since JPEG 2000 images don't render natively in browsers, you'll probably have to convert them to something that browsers can render before using them on a web-page. The easiest way to do this would be to just convert the images server side to some web-safe format then serve the converted images to the browser. However, if you're determined to do it client side then, then there is an example of using JavaScript to decode JPEG 2000 images here: https://github.com/kripken/j2k.js/blob/master/examples/simple.html.

This works using a JavaScript compilation of the OpenJPEG library, available here. This this is an automatic conversion it's not the nicest to use, but they supply the following function makes it's use a bit easier:

// 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;
}

Here data is expected to be JavaScript array of bytes (well JavaScript numbers with values between 0 and 255 inclusive) as in the example file. You could get this by converting the images to this form server side, or Ajaxing them in and treating the response as binary data (see MDN's using XHR's on how to do this for Firefox at least, other browsers probably need different methods). The output of this function is then put into a Canvas element like so:

  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);

Since this uses the Canvas element means this won't work in IE8, but for that it might be possible to do something else. For example, you could try getting the converted image data in the right format for a bitmap or some other simple IE compatible format, base64 encoding it then sticking it in as the source of an image element, see http://css-tricks.com/data-uris/ for examples of how to use data urls like this.

Illustrative answered 14/3, 2012 at 14:14 Comment(2)
Thank you very much! I've tried that JavaScript library (J2K.js) and worked perfect! the problem was only with image that sizes where less than 1MB, if the size is higher it won't work. Because we are using DICOM image (5 MB size in J2K) it doesn't work fine for us. But i'll try to use AJAX. Thanks again.Decree
Please note that the URL to the j2k.js library has changed. I edited the answer, but I suspect that there's still work to be done.Guide
T
7

I believe the pdf.js project can decode JPEG2000 images compressed in a PDF file. See this code comment section from the project's stream.js file, and this Tweet:

We now support JPEG 2000 images thanks to a "little" 2000 line js jpx decoder @notmasteryet whipped up in less than a month.

- 2:36 PM · Jan 20, 2012

Tremolite answered 1/3, 2012 at 10:13 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.