Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Low memory image resizing

I am looking for some advice on how to construct a very low memory image resizing program that will be run as a child process of my nodejs application in linux.

The solution I am looking for is a linux executable that will take a base64 string image (uploaded from a client) using stdin, resizing the photo to a specified size and then pumping the resulting image data back through stdout.

I've looked into image magick and it might be what I end up using, but I figured I would ask and see if anyone had a suggestion.

Suggestions of libraries or examples of pre compiled executables in C/C++ would be greatly appreciated. Also a helpful answer would include general strategies for low memory image resizing.

Thank you

like image 364
Skawful Avatar asked Nov 30 '10 06:11

Skawful


People also ask

Does resizing an image reduce quality?

Frequently asked questions: Does resizing an image affect its quality? It definitely can! Typically, making an image smaller will not impact the quality, but an image can suffer quality loss when scaled beyond its original size.

How can I increase the kB of a picture?

Double-click the white file size text field above the folder to select its contents, then type the kB size you want the photo to be. If you need your file to be larger, you'll type in a number that's larger than the number currently listed here (and vice versa).


3 Answers

Depending on the image formats you want to support, it's almost surely possible to perform incremental decoding and scaling by decoding only a few lines at a time and discarding the data once you write the output. However it may require writing your own code or adapting an existing decoder library to support this kind of operation.

It's also worth noting that downsizing giant jpegs can be performed efficiently by simply skipping the high-frequency coefficients and using a smaller IDCT. For example, to decode at half width and half height, discard all but the upper-left quadrant of the coefficients (horizontal and vertical frequency < 4) and use a 4x4 IDCT on them instead of the usual 8x8. Both the libjpeg decoder and the libavcodec decoder support this operation for power-of-2 scalings (1/2, 1/4, or 1/8). This type of approach might make incremental decoding/scaling unnecessary.

You can try it out with djpeg -scale 1/4 < src.jpg | cjpeg > dest.jpg. If you want a fixed output size, you'll probably first scale by whichever of 1/2, 1/4, or 1/8 puts you closest to the desired size without going to low, then performing interpolation to go the final step, e.g. djpeg -scale 1/4 < src.jpg | convert pnm:- -scale 640x480 dest.jpg.

like image 174
R.. GitHub STOP HELPING ICE Avatar answered Sep 20 '22 23:09

R.. GitHub STOP HELPING ICE


When working on very large images, such as 0.25 GPix and larger, ImageMagick uses ~2 GB ram, even when using djpeg to decode the JPEG image first.

This command chain will resize JPEG images of about any size using only ~3 MB ram:

djpeg my-large.jpg | pnmscale -xysize 16000 16000 | cjpeg > scaled-large.jpg
like image 26
hovenko Avatar answered Sep 22 '22 23:09

hovenko


GraphicsMagick is generally a better version of ImageMagick, I'd take a look at that. If you really need something fast, you probably want to drop to something like libjpeg - while you say you want something that's non-blocking IO, the operation you want to do is relatively CPU-bound (i.e decoding the image, then trying to resize it).

like image 37
Ana Betts Avatar answered Sep 22 '22 23:09

Ana Betts