JAI - Out of memory during encoding.

P

Patrick Boulay

Hi,

I'm trying to open a big tiff, 3400x4680, 16 million colors. I do this
operation and I get out of memory after 5 min.

- Open the file
- Resize the file to 1700x2340
- Converting to gray scale
- Converting to a bilevel format
- Encode this file to a tif, 200dpi, to an ouput stream

Look my code:
*********************************************
// Loading the file
PlanarImage img = JAI.create("fileload", f.getPath());
....
//Resizing the file
ParameterBlock parameterBlock = new ParameterBlock();
parameterBlock.addSource(img);
parameterBlock.add(scale);
parameterBlock.add(scale);
parameterBlock.add(0.0f);
parameterBlock.add(0.0f);
parameterBlock.add(Interpolation.getInstance(Interpolation.INTERP_BILINEAR));
Planar newImg = JAI.create("scale", parameterBlock);
// Get the gray image
PlanarImage imgGray = colorToGray(newImg);
// Convert to a bilevel image
PlanarImage newImg = toBilevel(imgGray);

// Set parameter for the new tif file
TIFFEncodeParam params = new TIFFEncodeParam();
params.setCompression(TIFFEncodeParam.COMPRESSION_GROUP3_2D);
TIFFField[] extras = new TIFFField[3];
extras[0] = new TIFFField(282, TIFFField.TIFF_RATIONAL, 1, (Object)new
long[][] {{(long)200, (long)1},{(long)0 ,(long)0}});
extras[1] = new TIFFField(283, TIFFField.TIFF_RATIONAL, 1, (Object)new
long[][] {{(long)200, (long)1},{(long)0 ,(long)0}});
extras[2] = new TIFFField(296, TIFFField.TIFF_SHORT, 1, (Object) new
char[] {2});

params.setExtraFields(extras);

//Set the encoder to my outputstream (DataOutputStream)
ImageEncoder encoder = ImageCodec.createImageEncoder("TIFF", out,
params);

encoder.encode(newImg);



public PlanarImage colorToGray(PlanarImage i)
{
double[][] matrix = { {0.114D, 0.587D, 0.299D, 0.0D} };
if (i.getSampleModel().getNumBands() == 3)
{
ParameterBlock pb = new ParameterBlock();
pb.addSource(i);
pb.add(matrix);
return ( (PlanarImage) JAI.create("bandcombine", pb, null));
}
return i;
}


public PlanarImage toBilevel(PlanarImage src) {
PlanarImage dst =
JAI.create("binarize", src, new Double(200));
return dst;
}

**********************************************


Everything work fine with smaller file... but with a big big file with
16million of colors, I got a out of memory in that operation
"encoder.encode(newImg);"

Anyone can help me?

Patrick
 
M

Michael David Pedersen

Hi,

Patrick Boulay said:
Hi,

I'm trying to open a big tiff, 3400x4680, 16 million colors. I do this
operation and I get out of memory after 5 min.

- Open the file
- Resize the file to 1700x2340
- Converting to gray scale
- Converting to a bilevel format
- Encode this file to a tif, 200dpi, to an ouput stream

Look my code:
*********************************************
// Loading the file
PlanarImage img = JAI.create("fileload", f.getPath());
...
//Resizing the file
ParameterBlock parameterBlock = new ParameterBlock();
parameterBlock.addSource(img);
parameterBlock.add(scale);
parameterBlock.add(scale);
parameterBlock.add(0.0f);
parameterBlock.add(0.0f);
parameterBlock.add(Interpolation.getInstance(Interpolation.INTERP_BILINEAR))
;
Planar newImg = JAI.create("scale", parameterBlock);
// Get the gray image
PlanarImage imgGray = colorToGray(newImg);
// Convert to a bilevel image
PlanarImage newImg = toBilevel(imgGray);

// Set parameter for the new tif file
TIFFEncodeParam params = new TIFFEncodeParam();
params.setCompression(TIFFEncodeParam.COMPRESSION_GROUP3_2D);
TIFFField[] extras = new TIFFField[3];
extras[0] = new TIFFField(282, TIFFField.TIFF_RATIONAL, 1, (Object)new
long[][] {{(long)200, (long)1},{(long)0 ,(long)0}});
extras[1] = new TIFFField(283, TIFFField.TIFF_RATIONAL, 1, (Object)new
long[][] {{(long)200, (long)1},{(long)0 ,(long)0}});
extras[2] = new TIFFField(296, TIFFField.TIFF_SHORT, 1, (Object) new
char[] {2});

params.setExtraFields(extras);

//Set the encoder to my outputstream (DataOutputStream)
ImageEncoder encoder = ImageCodec.createImageEncoder("TIFF", out,
params);

encoder.encode(newImg);



public PlanarImage colorToGray(PlanarImage i)
{
double[][] matrix = { {0.114D, 0.587D, 0.299D, 0.0D} };
if (i.getSampleModel().getNumBands() == 3)
{
ParameterBlock pb = new ParameterBlock();
pb.addSource(i);
pb.add(matrix);
return ( (PlanarImage) JAI.create("bandcombine", pb, null));
}
return i;
}


public PlanarImage toBilevel(PlanarImage src) {
PlanarImage dst =
JAI.create("binarize", src, new Double(200));
return dst;
}

**********************************************


Everything work fine with smaller file... but with a big big file with
16million of colors, I got a out of memory in that operation
"encoder.encode(newImg);"

Anyone can help me?

Patrick

This may be caused by a maximum heap size setting for your virtual machine
being too small. Try passing the max heap size as a parameter to java,
e.g. -Xmx256m for 256Mb.

I think this issue is also mentioned in the JAI faq, along with some other
causes and solutions:

http://java.sun.com/products/java-media/jai/forDevelopers/jaifaq.html#memory1

Regards,
Michael.
 
R

Roedy Green

I'm trying to open a big tiff, 3400x4680, 16 million colors. I do this
operation and I get out of memory after 5 min.

- Open the file
- Resize the file to 1700x2340
- Converting to gray scale
- Converting to a bilevel format
- Encode this file to a tif, 200dpi, to an ouput stream

If tiff is not a compressed format, perhaps you can do this job in 4
tiles, and then stitch the results together. You would have to do
some i/o to just bring into ram the tile you wanted to work on.

Working the way you are, make sure you nullify references to the
various intermediates so they won't be soaking up RAM.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,968
Messages
2,570,154
Members
46,701
Latest member
XavierQ83

Latest Threads

Top