george_h
george_h

Reputation: 1592

How do I crop an image without loading it into memory using Java

Is there a way to crop an image without having the load the entire image into memory and cropping it then?

The scenario is that I have a really really big image file and I have a list of rectangular coordinates that I need to crop out of the big image. The image is so huge I can't directly load it into memory. Is there a technique I can stream the image and sort of find the start and end points to crop? Don't mind if I have to perform this step many times for each set of coordinates. Oh yeah, assuming the images are of format JPG/PNG/TIFF which ever one is easiest to work with.

Should be able to run on Windows and Linux should there be any dependencies on native libraries.

Thanks.

Upvotes: 2

Views: 1036

Answers (1)

Mark Setchell
Mark Setchell

Reputation: 208052

You can use libvips to do this - it is available for Linux, OSX and Windows.

To get set up, let's use ImageMagick to create a big image (10,000x10,000) that is difficult to compress because it is full of random noise:

convert -size 10000x10000 xc:gray +noise random  \
   -fill red  -draw "rectangle 0,0 100,100"      \
   -fill blue -draw "rectangle 9900,9900 10000,10000" BigBoy.tif

Reduced in size, it looks like this, with a red rectangle in the top-left and a blue rectangle in the bottom-right if you look closely:

enter image description here

and weighs in at 800 MB:

-rw-r--r--@  1 mark  staff  800080278  5 May 12:08 BigBoy.tif

Now let's use libvips (just at the command-line) to extract the top-left and bottom-right corners (which are readily identifiable - did you see what I did there?):

vips im_extract_area BigBoy.tif topleft.jpg 0 0 200 200 --vips-leak
memory: high-water mark 118.85 MB

enter image description here

vips im_extract_area BigBoy.tif bottomright.jpg 9800 9800 200 200 --vips-leak
memory: high-water mark 118.85 MB

enter image description here

Both commands used around 120MB of memory. I don't believe there are Java bindings for libvips, but I presume you can fork() and exec() stuff or use something like C's system() function.

Upvotes: 1

Related Questions