5

Since browsers know how to handle JPG files, is there a way to give them the actual binary data of a JPG file dynamically and allowing them to decode it?

I can't supply the file as a normal image.src="path.jpg" because the data is originally a part of another file which is parsed in JS.

In addition, I have weird JPG files that store alpha, and so libraries like https://github.com/notmasteryet/jpgjs can't handle them.

4
  • There's no way to make the browser read binary code, closest you'll get is probably base64, which modern browsers will read. Commented Apr 26, 2014 at 11:07
  • To get the base64 string I'll need to decode the JPG first, which goes back to the start. Commented Apr 26, 2014 at 11:11
  • What does "weird JPG files that store alpha" mean? Is this really 2 image files: jpg + greyscale image representing the alpha channel? If yes, then (1) separate the 2 images, (2) decode them with a library like your jpgjs, (3) create 2 javascript Image objects from the decoded jpgs, (4) create 2 canvases and drawImage both images to canvas, (5) use context.getImageData to combine the rgb channels from the color .jpg with the alpha mask from the grayscale .jpg, (6) use context.putImageData to write the combined pixel data to canvas, (7) use canvas.toDataURL to create base64 image data. Commented Apr 26, 2014 at 11:56
  • I edited the above jpgjs a little, and it seems like the colors are simply stored as BGRA instead of YCbCr. If I avoid the later check (that sees the format has 4 components, which it doesn't like), I can get the values just fine. I'd still prefer the browser to do the decoding, since it's better at it, but whatever. Thanks for the comments. Commented Apr 26, 2014 at 12:06

1 Answer 1

12

You can use Blobs to create objects from binary data that you later pass as an url for image decoding. Assuming you have the binary data stored as typed array you could do something like this:

var blob = new Blob([myTypedArray], {type: 'application/octet-binary'});
var url = URL.createObjectURL(blob);

Now you can pass that url as a source for image:

var img = new Image;
img.onload = function() {
    URL.revokeObjectURL(url);
    ...
};
img.src = url;

Note that you still have make sure that the data you pass in is valid image format that the browser can handle.

Sign up to request clarification or add additional context in comments.

4 Comments

That looks brilliant, but sadly it drops the alpha channel (all of it becomes opaque) :(
The pixels where the alpha wasn't opaque are changed, so I assume the browser pre-multiplies the alpha channel and then removes it. Too bad, because this is brilliant and fast (and quite smaller than a 30KB+ decoder).
@user2503048 It seems JPG spec doesn't officially support alpha, right? Therefore I wouldn't be surprised that this answer doesn't work with alpha channels. PNG files with alpha channels would work using this technique though, because PNG supports alpha.
JPEG doesn't support the alpha channel.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.