tags:

views:

206

answers:

2

Does anyone know of any code that does streaming Jpeg resizing. What I mean by this is reading a chunk of an image (depending on the original source and destination size this would obviously vary), and resizing it, allowing for lower memory consumption when resizing very large jpegs. Obviously this wouldn't work for progressive jpegs (or at least it would become much more complicated), but it should be possible for standard jpegs.

+1  A: 

The design of JPEG data allows simple resizing to 1/2, 1/4 or 1/8 size. Other variations are possible. These same size reductions are easy to do on progressive jpegs as well and the quantity of data to parse in a progressive file will be much less if you want a reduced size image. Beyond that, your question is not specific enough to know what you really want to do.

Another simple trick to reduce the data size by 33% is to render the image into a RGB565 bitmap instead of RGB24 (if you don't need the full color space).

BitBank
What I want to do is be able to convert a 150 MegaPixel image to a smaller size (for example 1 MegaPixel) without having to use 500 Megs of memory to load the image into memory. I want to be able to load smaller chunks into memory and work on those, rather than the entire block.
Kris Erickson
What you're wanting to do will require custom code. I've written my own JPEG decoder from scratch that could be adapted to your purpose without much trouble. The x/y decode loops will need to have a fractional number of pixels rendered per line/row. Integer divisions will certainly be easiest to implement. Contact me if you need additional help - [email protected]
BitBank
A: 

I don't know of a library that can do this off the shelf, but it's certainly possible.

Lets say your JPEG is using 8x8 pixel MCUs (the units in which pixels are grouped). Lets also say you are reducing by a factor to 12 to 1. The first output pixel needs to be the average of the 12x12 block of pixels at the top left of the input image. To get to the input pixels with a y coordinate greater than 8, you need to have decoded the start of the second row of MCUs. You can't really get to decode those pixels before decoding the whole of the first row of MCUs. In practice, that probably means you'll need to store two rows of decoded MCUs. Still, for a 12000x12000 pixel image (roughly 150 mega pixels) you'd reduce the memory requirements by a factor of 12000/16 = 750. That should be enough for a PC. If you're looking at embedded use, you could horizontally resize the rows of MCUs as you read them, reducing the memory requirements by another factor of 12, at the cost of a little more code complexity.

I'd find a simple jpeg decoder library like Tiny Jpeg Decoder and look at the main loop in the jpeg decode function. In the case of Tiny Jpeg Decoder, the main loop calls decode_MCU, Modify from there. :-)

You've got a bunch of fiddly work to do to make the code work for none 8x8 MCUs and a load more if you want to reduce by a none integer factor. Sounds like fun though. Good luck.

Andrew Bainbridge