The Source for Java Technology Collaboration

Home » java.net Forums » Java Desktop Technologies » JAI

Thread: using JAI to create a thumbnail as a JPEG

Welcome, Guest Help
Login Login
Guest Settings Guest Settings
This question is not answered. Helpful answers available: 2. Correct answers available: 1.

Reply to this Thread Reply to this Thread Search Forum Search Forum Back to Thread List Back to Thread List

Permlink Replies: 13 - Last Post: Oct 19, 2007 10:56 AM by: b06
mlevin

Posts: 1
using JAI to create a thumbnail as a JPEG
Posted: May 6, 2007 7:51 PM
 
  Click to reply to this thread Reply

I'm trying to use JAI to create a thumbnail of a JPEG and no matter what I do, I keep getting the following stack trace:

exception

javax.servlet.ServletException: All factories fail for the operation "encode"
org.apache.struts.action.RequestProcessor.processException(RequestProcessor.java:523)
org.apache.struts.action.RequestProcessor.processActionPerform(RequestProcessor.java:421)
org.apache.struts.action.RequestProcessor.process(RequestProcessor.java:224)
org.apache.struts.action.ActionServlet.process(ActionServlet.java:1194)
org.apache.struts.action.ActionServlet.doPost(ActionServlet.java:432)
javax.servlet.http.HttpServlet.service(HttpServlet.java:709)
javax.servlet.http.HttpServlet.service(HttpServlet.java:802)

root cause

javax.media.jai.util.ImagingException: All factories fail for the operation "encode"
javax.media.jai.OperationRegistry.invokeFactory(OperationRegistry.java:1687)
javax.media.jai.ThreadSafeOperationRegistry.invokeFactory(ThreadSafeOperationRegistry.java:473)
javax.media.jai.registry.RIFRegistry.create(RIFRegistry.java:332)
javax.media.jai.RenderedOp.createInstance(RenderedOp.java:819)
javax.media.jai.RenderedOp.createRendering(RenderedOp.java:867)
javax.media.jai.RenderedOp.getRendering(RenderedOp.java:888)
javax.media.jai.JAI.createNS(JAI.java:1099)
javax.media.jai.JAI.create(JAI.java:973)
javax.media.jai.JAI.create(JAI.java:1395)
UploadAction.resizeImage(UploadAction.java:111)
UploadAction.execute(UploadAction.java:71)
org.apache.struts.action.RequestProcessor.processActionPerform(RequestProcessor.java:419)
org.apache.struts.action.RequestProcessor.process(RequestProcessor.java:224)
org.apache.struts.action.ActionServlet.process(ActionServlet.java:1194)
org.apache.struts.action.ActionServlet.doPost(ActionServlet.java:432)
javax.servlet.http.HttpServlet.service(HttpServlet.java:709)
javax.servlet.http.HttpServlet.service(HttpServlet.java:802)

root cause

java.io.IOException: reading encoded JPEG Stream
sun.awt.image.codec.JPEGImageEncoderImpl.writeJPEGStream(Native
Method)
sun.awt.image.codec.JPEGImageEncoderImpl.encode(JPEGImageEncoderImpl.java:472)
sun.awt.image.codec.JPEGImageEncoderImpl.encode(JPEGImageEncoderImpl.java:228)
com.sun.media.jai.codecimpl.JPEGImageEncoder.encode(JPEGImageEncoder.java:277)
com.sun.media.jai.opimage.EncodeRIF.create(EncodeRIF.java:70)
sun.reflect.GeneratedMethodAccessor51.invoke(Unknown Source)
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
java.lang.reflect.Method.invoke(Method.java:585)
javax.media.jai.FactoryCache.invoke(FactoryCache.java:122)
javax.media.jai.OperationRegistry.invokeFactory(OperationRegistry.java:1674)
javax.media.jai.ThreadSafeOperationRegistry.invokeFactory(ThreadSafeOperationRegistry.java:473)
javax.media.jai.registry.RIFRegistry.create(RIFRegistry.java:332)
javax.media.jai.RenderedOp.createInstance(RenderedOp.java:819)
javax.media.jai.RenderedOp.createRendering(RenderedOp.java:867)
javax.media.jai.RenderedOp.getRendering(RenderedOp.java:888)
javax.media.jai.JAI.createNS(JAI.java:1099)
javax.media.jai.JAI.create(JAI.java:973)
javax.media.jai.JAI.create(JAI.java:1395)
UploadAction.resizeImage(UploadAction.java:111)
UploadAction.execute(UploadAction.java:71)
org.apache.struts.action.RequestProcessor.processActionPerform(RequestProcessor.java:419)
org.apache.struts.action.RequestProcessor.process(RequestProcessor.java:224)
org.apache.struts.action.ActionServlet.process(ActionServlet.java:1194)
org.apache.struts.action.ActionServlet.doPost(ActionServlet.java:432)
javax.servlet.http.HttpServlet.service(HttpServlet.java:709)
javax.servlet.http.HttpServlet.service(HttpServlet.java:802)

The code I'm using is cobbled together from several examples and clearly I'm not doing something right. Here's what I've got so far:

import java.awt.RenderingHints;
import java.awt.image.BufferedImage;
import java.awt.image.renderable.ParameterBlock;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

import javax.media.jai.Interpolation;
import javax.media.jai.JAI;
import javax.media.jai.OpImage;
import javax.media.jai.RenderedOp;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.struts.action.Action;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;

import com.sun.media.jai.codec.JPEGEncodeParam;
import com.sun.media.jai.codec.PNGEncodeParam;
import com.sun.media.jai.codec.SeekableStream;

public class UploadAction extends Action {

public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws IOException {

String basePath = "C:\\Program Files\\Apache Software Foundation\\Tomcat 5.5\\webapps\\strutsTest\\";

UploadForm upload = (UploadForm) form;

if (upload.getFile() != null) {
/*
*
*
*
*
*
*/

// open input stream from uploaded file and copy into byte array
InputStream is = new BufferedInputStream(upload.getFile().getInputStream());
ByteArrayOutputStream bos = new ByteArrayOutputStream();
int bytesRead = 0;
byte[] buffer = new byte[8192];
while ((bytesRead = is.read(buffer, 0, 8192)) != -1) {
bos.write(buffer, 0, bytesRead);
}
bos.close();
is.close();
byte[] image = bos.toByteArray();

// write original (unresized) file
OutputStream os = new BufferedOutputStream(new
FileOutputStream(basePath + upload.getFile().getFileName()));
ByteArrayInputStream bis = new ByteArrayInputStream(image);
bytesRead = 0;
buffer = new byte[8192];
while ((bytesRead = bis.read(buffer, 0, 8192)) != -1) {
os.write(buffer, 0, bytesRead);
}
os.close();

// resize image
bis.reset();
OutputStream osThumb = new BufferedOutputStream(new
FileOutputStream(basePath + "THUMB_" +
upload.getFile().getFileName()));
resizeImage(bis, os, 150, 150);
osThumb.close();

// close input stream
bis.close();

}

return mapping.findForward("success");

}

// based on code examples from http://www.iproving.ca/space/Technologies/Java+Advanced+Imaging, http://forums.java.net/jive/thread.jspa?messageID=64672 and http://archives.java.sun.com/cgi-bin/wa?A2=ind0208&L=java-imageio-interest&P=242
private void resizeImage(InputStream is, OutputStream os, int width,
int height) {

// read in the original image from an input stream
SeekableStream s = SeekableStream.wrapInputStream(is, true);
RenderedOp image = JAI.create("stream", s);
((OpImage) image.getRendering()).setTileCache(null);

// now resize the image
double hRatio = ((double) height) / ((double) image.getHeight());
double wRatio = ((double) width) / ((double) image.getWidth());
double scale = Math.min(hRatio, wRatio);
ParameterBlock pb = new ParameterBlock();
pb.addSource(image).add(scale).add(scale);
pb.add(Interpolation.getInstance(Interpolation.INTERP_BICUBIC));
RenderingHints qualityHints = new
RenderingHints(RenderingHints.KEY_RENDERING,
RenderingHints.VALUE_RENDER_QUALITY);
RenderedOp resizedImage = JAI.create("SubsampleAverage", pb,
qualityHints);

// lastly, write the newly-resized image to an
// output stream, in a specific encoding
pb = new ParameterBlock();
BufferedImage bi = resizedImage.getAsBufferedImage();
pb.addSource(bi);
pb.add(os);
pb.add("jpeg");
JPEGEncodeParam ep = new JPEGEncodeParam();
ep.setQuality(0.75f);
pb.add(ep);
JAI.create("encode", pb);

}

}

Any suggestions? I'm baffled.

Thanks

martinrleon
Re: [JAI] using JAI to create a thumbnail as a JPEG
Posted: Jun 6, 2007 6:15 PM   in response to: mlevin
  Click to reply to this thread Reply


I'm not sure it will work, but maybe let the JPEGCodec automatically create
the codec and params for you:

final JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder( os );
final JPEGEncodeParam ep = encoder.getDefaultJPEGEncodeParam( bi );

ep.setQuality( 0.75f , false );


jai-interest wrote:
>
> I'm trying to use JAI to create a thumbnail of a JPEG and no matter what I
> do, I keep getting the following stack trace:
>
> exception
>
> javax.servlet.ServletException: All factories fail for the operation
> "encode"
>
> org.apache.struts.action.RequestProcessor.processException(RequestProcessor.java:523)
>
> org.apache.struts.action.RequestProcessor.processActionPerform(RequestProcessor.java:421)
>
> org.apache.struts.action.RequestProcessor.process(RequestProcessor.java:224)
> org.apache.struts.action.ActionServlet.process(ActionServlet.java:1194)
> org.apache.struts.action.ActionServlet.doPost(ActionServlet.java:432)
> javax.servlet.http.HttpServlet.service(HttpServlet.java:709)
> javax.servlet.http.HttpServlet.service(HttpServlet.java:802)
>
> root cause
>
> javax.media.jai.util.ImagingException: All factories fail for the
> operation "encode"
>
> javax.media.jai.OperationRegistry.invokeFactory(OperationRegistry.java:1687)
>
> javax.media.jai.ThreadSafeOperationRegistry.invokeFactory(ThreadSafeOperationRegistry.java:473)
> javax.media.jai.registry.RIFRegistry.create(RIFRegistry.java:332)
> javax.media.jai.RenderedOp.createInstance(RenderedOp.java:819)
> javax.media.jai.RenderedOp.createRendering(RenderedOp.java:867)
> javax.media.jai.RenderedOp.getRendering(RenderedOp.java:888)
> javax.media.jai.JAI.createNS(JAI.java:1099)
> javax.media.jai.JAI.create(JAI.java:973)
> javax.media.jai.JAI.create(JAI.java:1395)
> UploadAction.resizeImage(UploadAction.java:111)
> UploadAction.execute(UploadAction.java:71)
>
> org.apache.struts.action.RequestProcessor.processActionPerform(RequestProcessor.java:419)
>
> org.apache.struts.action.RequestProcessor.process(RequestProcessor.java:224)
> org.apache.struts.action.ActionServlet.process(ActionServlet.java:1194)
> org.apache.struts.action.ActionServlet.doPost(ActionServlet.java:432)
> javax.servlet.http.HttpServlet.service(HttpServlet.java:709)
> javax.servlet.http.HttpServlet.service(HttpServlet.java:802)
>
> root cause
>
> java.io.IOException: reading encoded JPEG Stream
> sun.awt.image.codec.JPEGImageEncoderImpl.writeJPEGStream(Native
> Method)
>
> sun.awt.image.codec.JPEGImageEncoderImpl.encode(JPEGImageEncoderImpl.java:472)
>
> sun.awt.image.codec.JPEGImageEncoderImpl.encode(JPEGImageEncoderImpl.java:228)
>
> com.sun.media.jai.codecimpl.JPEGImageEncoder.encode(JPEGImageEncoder.java:277)
> com.sun.media.jai.opimage.EncodeRIF.create(EncodeRIF.java:70)
> sun.reflect.GeneratedMethodAccessor51.invoke(Unknown Source)
>
> sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
> java.lang.reflect.Method.invoke(Method.java:585)
> javax.media.jai.FactoryCache.invoke(FactoryCache.java:122)
>
> javax.media.jai.OperationRegistry.invokeFactory(OperationRegistry.java:1674)
>
> javax.media.jai.ThreadSafeOperationRegistry.invokeFactory(ThreadSafeOperationRegistry.java:473)
> javax.media.jai.registry.RIFRegistry.create(RIFRegistry.java:332)
> javax.media.jai.RenderedOp.createInstance(RenderedOp.java:819)
> javax.media.jai.RenderedOp.createRendering(RenderedOp.java:867)
> javax.media.jai.RenderedOp.getRendering(RenderedOp.java:888)
> javax.media.jai.JAI.createNS(JAI.java:1099)
> javax.media.jai.JAI.create(JAI.java:973)
> javax.media.jai.JAI.create(JAI.java:1395)
> UploadAction.resizeImage(UploadAction.java:111)
> UploadAction.execute(UploadAction.java:71)
>
> org.apache.struts.action.RequestProcessor.processActionPerform(RequestProcessor.java:419)
>
> org.apache.struts.action.RequestProcessor.process(RequestProcessor.java:224)
> org.apache.struts.action.ActionServlet.process(ActionServlet.java:1194)
> org.apache.struts.action.ActionServlet.doPost(ActionServlet.java:432)
> javax.servlet.http.HttpServlet.service(HttpServlet.java:709)
> javax.servlet.http.HttpServlet.service(HttpServlet.java:802)
>
> The code I'm using is cobbled together from several examples and clearly
> I'm not doing something right. Here's what I've got so far:
>
> import java.awt.RenderingHints;
> import java.awt.image.BufferedImage;
> import java.awt.image.renderable.ParameterBlock;
> import java.io.BufferedInputStream;
> import java.io.BufferedOutputStream;
> import java.io.ByteArrayInputStream;
> import java.io.ByteArrayOutputStream;
> import java.io.FileOutputStream;
> import java.io.IOException;
> import java.io.InputStream;
> import java.io.OutputStream;
>
> import javax.media.jai.Interpolation;
> import javax.media.jai.JAI;
> import javax.media.jai.OpImage;
> import javax.media.jai.RenderedOp;
> import javax.servlet.http.HttpServletRequest;
> import javax.servlet.http.HttpServletResponse;
>
> import org.apache.struts.action.Action;
> import org.apache.struts.action.ActionForm;
> import org.apache.struts.action.ActionForward;
> import org.apache.struts.action.ActionMapping;
>
> import com.sun.media.jai.codec.JPEGEncodeParam;
> import com.sun.media.jai.codec.PNGEncodeParam;
> import com.sun.media.jai.codec.SeekableStream;
>
> public class UploadAction extends Action {
>
> public ActionForward execute(ActionMapping mapping, ActionForm form,
> HttpServletRequest request, HttpServletResponse response) throws
> IOException {
>
> String basePath = "C:\\Program Files\\Apache Software Foundation\\Tomcat
> 5.5\\webapps\\strutsTest\\";
>
> UploadForm upload = (UploadForm) form;
>
> if (upload.getFile() != null) {
> /*
> *
> *
> *
> *
> *
> */
>
> // open input stream from uploaded file and copy into byte array
> InputStream is = new
> BufferedInputStream(upload.getFile().getInputStream());
> ByteArrayOutputStream bos = new ByteArrayOutputStream();
> int bytesRead = 0;
> byte[] buffer = new byte[8192];
> while ((bytesRead = is.read(buffer, 0, 8192)) != -1) {
> bos.write(buffer, 0, bytesRead);
> }
> bos.close();
> is.close();
> byte[] image = bos.toByteArray();
>
> // write original (unresized) file
> OutputStream os = new BufferedOutputStream(new
> FileOutputStream(basePath + upload.getFile().getFileName()));
> ByteArrayInputStream bis = new ByteArrayInputStream(image);
> bytesRead = 0;
> buffer = new byte[8192];
> while ((bytesRead = bis.read(buffer, 0, 8192)) != -1) {
> os.write(buffer, 0, bytesRead);
> }
> os.close();
>
> // resize image
> bis.reset();
> OutputStream osThumb = new BufferedOutputStream(new
> FileOutputStream(basePath + "THUMB_" +
> upload.getFile().getFileName()));
> resizeImage(bis, os, 150, 150);
> osThumb.close();
>
> // close input stream
> bis.close();
>
> }
>
> return mapping.findForward("success");
>
> }
>
> // based on code examples from
> http://www.iproving.ca/space/Technologies/Java+Advanced+Imaging,
> http://forums.java.net/jive/thread.jspa?messageID=64672 and
> http://archives.java.sun.com/cgi-bin/wa?A2=ind0208&L=java-imageio-interest&P=242
> private void resizeImage(InputStream is, OutputStream os, int width,
> int height) {
>
> // read in the original image from an input stream
> SeekableStream s = SeekableStream.wrapInputStream(is, true);
> RenderedOp image = JAI.create("stream", s);
> ((OpImage) image.getRendering()).setTileCache(null);
>
> // now resize the image
> double hRatio = ((double) height) / ((double) image.getHeight());
> double wRatio = ((double) width) / ((double) image.getWidth());
> double scale = Math.min(hRatio, wRatio);
> ParameterBlock pb = new ParameterBlock();
> pb.addSource(image).add(scale).add(scale);
> pb.add(Interpolation.getInstance(Interpolation.INTERP_BICUBIC));
> RenderingHints qualityHints = new
> RenderingHints(RenderingHints.KEY_RENDERING,
> RenderingHints.VALUE_RENDER_QUALITY);
> RenderedOp resizedImage = JAI.create("SubsampleAverage", pb,
> qualityHints);
>
> // lastly, write the newly-resized image to an
> // output stream, in a specific encoding
> pb = new ParameterBlock();
> BufferedImage bi = resizedImage.getAsBufferedImage();
> pb.addSource(bi);
> pb.add(os);
> pb.add("jpeg");
> JPEGEncodeParam ep = new JPEGEncodeParam();
> ep.setQuality(0.75f);
> pb.add(ep);
> JAI.create("encode", pb);
>
> }
>
> }
>
> Any suggestions? I'm baffled.
>
> Thanks
> [Message sent by forum member 'mlevin' (mlevin)]
>
> http://forums.java.net/jive/thread.jspa?messageID=215776
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: interest-unsubscribe@jai.dev.java.net
> For additional commands, e-mail: interest-help@jai.dev.java.net
>
>
>

--
View this message in context: http://www.nabble.com/using-JAI-to-create-a-thumbnail-as-a-JPEG-tf3701670.html#a11000310
Sent from the JAI Projects - Interest mailing list archive at Nabble.com.

---------------------------------------------------------------------
To unsubscribe, e-mail: interest-unsubscribe@jai.dev.java.net
For additional commands, e-mail: interest-help@jai.dev.java.net


martinrleon
Re: [JAI] using JAI to create a thumbnail as a JPEG
Posted: Jun 9, 2007 10:28 AM   in response to: mlevin
  Click to reply to this thread Reply


Give it up! I tried and tried to find a way to create a thumbnail using JAI
and there seems to be a fundamental flaw with JAI - there doesn't seem to be
a way to perform any JAI operations that don't attempt to load the entire
image into memory, requiring ridiculous amounts of memory. Every JAI
operation that I could think of or could find reference to causes the image
to be loaded. On the Sun Java forums for JAI they recommend setting the
TileCache memory via TileCache.setMemoryCapacity and
TileCach.setMemoryThreshold. all to no avail. So I finally gave up on using
JAI to create thumbnails.

I found that the same thing occurs with the Java AWT image classes, which
cause the entire image to be loaded in order to even get the image dimension
information such as width and height, which you need in order to figure out
how to scale or subsample the original image in order to be able to generate
a smaller version. As I was researching this, I found some advice in a Sun
Java forum and came up with the code below which uses ImageIO to create
thumbnails. Using ImageIO you can get the image dimension information
without having to render the image in memory. With that information you can
subsample the image data, yielding a much smaller rendered image! The code
below demonstrates this. I hope this helps someone, it's taken me days to
figure this out.

My approach involves using an ImageIO ImageReader to get the dimension
information so I can compute how to subsample the source image. I subsample
a slightly larger number (25%) of pixels into an intermediate thumbnail
image that is slightly larger than the desired thumbnail size so I can use
interpolation in order to get a better quality thumbnail image. From the
intermediate thumbnail image I render down to the final thumbnail image and
store it in a file.

This worked with a 40MB PNG file and a 7MB JPG file. I also tried TIFF but
there doesn't seem to be an image reader for TIFF in the 1.4.2 Java that I
am working with. I'm assuming there is a way to add TIFF support, but I
don't really need to support TIFF.

import java.awt.Frame;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.image.BufferedImage;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;

import javax.imageio.ImageIO;
import javax.imageio.ImageReadParam;
import javax.imageio.ImageReader;
import javax.imageio.stream.ImageInputStream;

import com.sun.image.codec.jpeg.JPEGCodec;
import com.sun.image.codec.jpeg.JPEGEncodeParam;
import com.sun.image.codec.jpeg.JPEGImageEncoder;

/*
* Created on Jun 9, 2007
*/

public class TestIIOthumbnails {

private final static String[] knownFormats;

static {
knownFormats = ImageIO.getReaderFormatNames();
for ( int x = 0 ; x < knownFormats.length ; x++ ) {
knownFormats[x] =]]]] 1.0d ) {
thumbnailHeight = (int) ( thumbnailDimension / imageRatio );
}
else {
thumbnailWidth = (int) ( thumbnailDimension * imageRatio );
}

int longEdge = ( Math.max( imgHeight , imgWidth ) );
int tempThumbnailEdge = (int) ( (float) thumbnailDimension *
1.25f );
int subSample = (int) ( (float) longEdge / (float)
tempThumbnailEdge );

final ImageReadParam readParam =
imgReader.getDefaultReadParam();
if ( subSample > 1 ) {
readParam.setSourceSubsampling( subSample , subSample , 0 ,
0 );
}

final BufferedImage tempThumbnailImage = imgReader.read( 0 ,
readParam );

final BufferedImage thumbnailImage = new BufferedImage(
thumbnailWidth , thumbnailHeight ,
BufferedImage.TYPE_INT_RGB );
final Graphics2D graphics2D = thumbnailImage.createGraphics();
graphics2D
.setRenderingHint( RenderingHints.KEY_INTERPOLATION ,
RenderingHints.VALUE_INTERPOLATION_BILINEAR );
graphics2D.drawImage( tempThumbnailImage , 0 , 0 ,
thumbnailWidth , thumbnailHeight , frame );

final String thumbnailFileName = getThumbnailFileName(
inputFile.getCanonicalPath() );
final File thumbnailFile = new File( thumbnailFileName );
final BufferedOutputStream thumbnailOut = new
BufferedOutputStream(
( new FileOutputStream( thumbnailFile ) ) , 4092 );
final JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(
thumbnailOut );
final JPEGEncodeParam encoderParam =
encoder.getDefaultJPEGEncodeParam( thumbnailImage );
encoderParam.setQuality( thumbnailQuality , false );
encoder.setJPEGEncodeParam( encoderParam );
encoder.encode( thumbnailImage );
thumbnailOut.close();

// Dispose of AWT components
graphics2D.dispose();
frame.dispose();

response = thumbnailFile;
}
catch( Exception e ) {
e.printStackTrace();
}
return response;
}

private static boolean isKnownFormat( String fileName ) {
boolean response = false;

if ( fileName == null || fileName.length() == 0 ) {
return response;
}
int extensionPosition = fileName.lastIndexOf( '.' );

if ( extensionPosition == -1 ) return response;

final String extension = knownAliases( fileName.substring(
extensionPosition ).toLowerCase() );

for ( int x = 0 ; x < knownFormats.length ; x++ ) {
if ( extension.equals( knownFormats[x] ) ) {
return true;
}
}

return response;
}

private static String knownAliases( String fileName ) {
final String extension = fileName.substring( fileName.lastIndexOf(
'.' ) ).toLowerCase();
if ( extension.equals( ".jpg" ) ) return ".jpeg";
if ( extension.equals( ".jpe" ) ) return ".jpeg";
if ( extension.equals( ".tif" ) ) return ".tiff";
return extension;
}

private static String getThumbnailFileName( String attachmentName ) {
String result = null;
int dotIndex = 0;

//

Bob Deen
Re: [JAI] using JAI to create a thumbnail as a JPEG
Posted: Jun 9, 2007 8:36 PM   in response to: martinrleon
  Click to reply to this thread Reply

Did you try the imageread operator in JAI, which wraps around Image I/O?

The problems you cite are not the fault of JAI per se, but of the jpeg
reader. If the reader is capable of tiling the image, then JAI will
make
use of it. Unfortunately the old-style codec-based jpeg reader that
is supplied with JAI is incapable of tiling the image on read, thus the
problems you saw.

So try "imageread" instead of "fileload" to use the new IIO plugin, and
see if that works easier.

-Bob

-----------cut here-----------clip & save-----------valuable
coupon-----------

On Jun 9, 2007, at 10:28 AM, martinrleon wrote:

>
> Give it up! I tried and tried to find a way to create a thumbnail
> using JAI
> and there seems to be a fundamental flaw with JAI - there doesn't
> seem to be
> a way to perform any JAI operations that don't attempt to load the
> entire
> image into memory, requiring ridiculous amounts of memory. Every JAI
> operation that I could think of or could find reference to causes
> the image
> to be loaded. On the Sun Java forums for JAI they recommend
> setting the
> TileCache memory via TileCache.setMemoryCapacity and
> TileCach.setMemoryThreshold. all to no avail. So I finally gave up
> on using
> JAI to create thumbnails.
>
> I found that the same thing occurs with the Java AWT image classes,
> which
> cause the entire image to be loaded in order to even get the image
> dimension
> information such as width and height, which you need in order to
> figure out
> how to scale or subsample the original image in order to be able to
> generate
> a smaller version. As I was researching this, I found some advice
> in a Sun
> Java forum and came up with the code below which uses ImageIO to
> create
> thumbnails. Using ImageIO you can get the image dimension information
> without having to render the image in memory. With that
> information you can
> subsample the image data, yielding a much smaller rendered image!
> The code
> below demonstrates this. I hope this helps someone, it's taken me
> days to
> figure this out.
>
> My approach involves using an ImageIO ImageReader to get the dimension
> information so I can compute how to subsample the source image. I
> subsample
> a slightly larger number (25%) of pixels into an intermediate
> thumbnail
> image that is slightly larger than the desired thumbnail size so I
> can use
> interpolation in order to get a better quality thumbnail image.
> From the
> intermediate thumbnail image I render down to the final thumbnail
> image and
> store it in a file.
>
> This worked with a 40MB PNG file and a 7MB JPG file. I also tried
> TIFF but
> there doesn't seem to be an image reader for TIFF in the 1.4.2 Java
> that I
> am working with. I'm assuming there is a way to add TIFF support,
> but I
> don't really need to support TIFF.
>
> import java.awt.Frame;
> import java.awt.Graphics2D;
> import java.awt.RenderingHints;
> import java.awt.image.BufferedImage;
> import java.io.BufferedInputStream;
> import java.io.BufferedOutputStream;
> import java.io.File;
> import java.io.FileInputStream;
> import java.io.FileOutputStream;
>
> import javax.imageio.ImageIO;
> import javax.imageio.ImageReadParam;
> import javax.imageio.ImageReader;
> import javax.imageio.stream.ImageInputStream;
>
> import com.sun.image.codec.jpeg.JPEGCodec;
> import com.sun.image.codec.jpeg.JPEGEncodeParam;
> import com.sun.image.codec.jpeg.JPEGImageEncoder;
>
> /*
> * Created on Jun 9, 2007
> */
>
> public class TestIIOthumbnails {
>
> private final static String[] knownFormats;
>
> static {
> knownFormats = ImageIO.getReaderFormatNames();
> for ( int x = 0 ; x < knownFormats.length ; x++ ) {
> knownFormats[x] = '.' + knownFormats[x].toLowerCase();
> }
> }
>
> public static void main( String[] args ) {
> int thumbnailDimension = 300;
> float thumbnailQuality = 0.5f;
>
> try {
>
> String[] fileNames = { "PIA03231.JPG" , "PIA03241.JPG" ,
> "PIA08814.JPG" , "PIA09201.JPG" , "PIA09202.JPG" ,
> "PIA09203.JPG" , "PIA09205.JPG" , "PIA09207.JPG" ,
> "PIA09259.JPG" , "large4.png" , "large3.png" ,
> "large2.png" , "large.png" , "marbles.tif" ,
> "xing_t24.tif" };
>
> for ( int x = 0 ; x < fileNames.length ; x++ ) {
> final File inputFile = new File( fileNames[x] );
> if ( !inputFile.exists() ) {
> System.out.println( "Unable to locate file: " +
> inputFile.getCanonicalPath() );
> continue;
> }
>
> final File thumbnailFile = makeThumbnailFile
> ( inputFile ,
> thumbnailDimension , thumbnailQuality );
> if ( thumbnailFile != null && thumbnailFile.exists
> () ) {
> System.out.println
> ( thumbnailFile.getCanonicalPath() + "
> succesfully created" );
> }
> else {
> System.out.println( "Unable to create thumbnail
> for " +
> inputFile.getCanonicalPath() );
> }
> }
> System.out.println( "Done." );
> }
> catch( Exception e ) {
> CommonLib.logException( e , CommonLib.notOnServer() );
> }
> }
>
> private static File makeThumbnailFile( File inputFile , int
> thumbnailDimension , float thumbnailQuality ) {
>
> File response = null;
>
> try {
> if ( inputFile == null ) {
> System.out.println( "Input file is null" );
> return response;
> }
> if ( !inputFile.exists() ) {
> System.out.println( "Input file does not exist: " +
> inputFile.getName() );
> return response;
> }
> if ( !isKnownFormat( inputFile.toString() ) ) {
> System.out.println( "Unsupported file format: " +
> inputFile.getName() );
> return response;
> }
>
> final Frame frame = new Frame();
> frame.addNotify();
>
> final String fileSuffix = knownAliases
> ( inputFile.getName()
> ).substring( 1 );
>
> final ImageReader imgReader = (ImageReader)
> ImageIO.getImageReadersBySuffix( fileSuffix ).next();
>
> final ImageInputStream bufferedInput =
> ImageIO.createImageInputStream( new BufferedInputStream(
> new FileInputStream( inputFile ) ) );
>
> imgReader.setInput( bufferedInput );
>
> int imgHeight = imgReader.getHeight( 0 );
> int imgWidth = imgReader.getWidth( 0 );
>
> double imageRatio = (double) imgWidth / (double)
> imgHeight;
> int thumbnailHeight = thumbnailDimension;
> int thumbnailWidth = thumbnailDimension;
>
> if ( imageRatio > 1.0d ) {
> thumbnailHeight = (int) ( thumbnailDimension /
> imageRatio );
> }
> else {
> thumbnailWidth = (int) ( thumbnailDimension *
> imageRatio );
> }
>
> int longEdge = ( Math.max( imgHeight , imgWidth ) );
> int tempThumbnailEdge = (int) ( (float)
> thumbnailDimension *
> 1.25f );
> int subSample = (int) ( (float) longEdge / (float)
> tempThumbnailEdge );
>
> final ImageReadParam readParam =
> imgReader.getDefaultReadParam();
> if ( subSample > 1 ) {
> readParam.setSourceSubsampling( subSample ,
> subSample , 0 ,
> 0 );
> }
>
> final BufferedImage tempThumbnailImage = imgReader.read
> ( 0 ,
> readParam );
>
> final BufferedImage thumbnailImage = new BufferedImage(
> thumbnailWidth , thumbnailHeight ,
> BufferedImage.TYPE_INT_RGB );
> final Graphics2D graphics2D =
> thumbnailImage.createGraphics();
> graphics2D
> .setRenderingHint
> ( RenderingHints.KEY_INTERPOLATION ,
> RenderingHints.VALUE_INTERPOLATION_BILINEAR );
> graphics2D.drawImage( tempThumbnailImage , 0 , 0 ,
> thumbnailWidth , thumbnailHeight , frame );
>
> final String thumbnailFileName = getThumbnailFileName(
> inputFile.getCanonicalPath() );
> final File thumbnailFile = new File( thumbnailFileName );
> final BufferedOutputStream thumbnailOut = new
> BufferedOutputStream(
> ( new FileOutputStream( thumbnailFile ) ) ,
> 4092 );
> final JPEGImageEncoder encoder =
> JPEGCodec.createJPEGEncoder(
> thumbnailOut );
> final JPEGEncodeParam encoderParam =
> encoder.getDefaultJPEGEncodeParam( thumbnailImage );
> encoderParam.setQuality( thumbnailQuality , false );
> encoder.setJPEGEncodeParam( encoderParam );
> encoder.encode( thumbnailImage );
> thumbnailOut.close();
>
> // Dispose of AWT components
> graphics2D.dispose();
> frame.dispose();
>
> response = thumbnailFile;
> }
> catch( Exception e ) {
> e.printStackTrace();
> }
> return response;
> }
>
> private static boolean isKnownFormat( String fileName ) {
> boolean response = false;
>
> if ( fileName == null || fileName.length() == 0 ) {
> return response;
> }
> int extensionPosition = fileName.lastIndexOf( '.' );
>
> if ( extensionPosition == -1 ) return response;
>
> final String extension = knownAliases( fileName.substring(
> extensionPosition ).toLowerCase() );
>
> for ( int x = 0 ; x < knownFormats.length ; x++ ) {
> if ( extension.equals( knownFormats[x] ) ) {
> return true;
> }
> }
>
> return response;
> }
>
> private static String knownAliases( String fileName ) {
> final String extension = fileName.substring
> ( fileName.lastIndexOf(
> '.' ) ).toLowerCase();
> if ( extension.equals( ".jpg" ) ) return ".jpeg";
> if ( extension.equals( ".jpe" ) ) return ".jpeg";
> if ( extension.equals( ".tif" ) ) return ".tiff";
> return extension;
> }
>
> private static String getThumbnailFileName( String
> attachmentName ) {
> String result = null;
> int dotIndex = 0;
>
> // Get the position of the . before the extension
> dotIndex = attachmentName.lastIndexOf( "." );
> // Get the extension of the current file
> final String extension = attachmentName.substring( dotIndex
> + 1 );
> // Get the file name without the extension
> result = attachmentName.substring( 0 , dotIndex );
> // Build the thumbnail file name
> result = result + "_thumb_" + extension + ".jpg";
>
> return result;
> }
> }
>
> --
> View this message in context: http://www.nabble.com/using-JAI-to-
> create-a-thumbnail-as-a-JPEG-tf3701670.html#a11042093
> Sent from the JAI Projects - Interest mailing list archive at
> Nabble.com.
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: interest-unsubscribe@jai.dev.java.net
> For additional commands, e-mail: interest-help@jai.dev.java.net
>

---------------------------------------------------------------------
To unsubscribe, e-mail: interest-unsubscribe@jai.dev.java.net
For additional commands, e-mail: interest-help@jai.dev.java.net


martinrleon
Re: [JAI] using JAI to create a thumbnail as a JPEG
Posted: Jun 10, 2007 2:11 AM   in response to: Bob Deen
  Click to reply to this thread Reply


Thanks for your response.

I can't find any documentation for the "imageread" operator. Is it bundled
with the standard 1.4 SE distribution or is it something I have to add? If
so, how do I add the ImageIO plugin to my JAI configuration and where can I
find documentation for it?

Thanks again for your response, I was incredulous about a newer API (JAI)
not being able to do what an older one could do (ImageIO) - I figured they
didn't want to make the effort when another API could already provide the
functionality.


Bob Deen wrote:
>
> Did you try the imageread operator in JAI, which wraps around Image I/O?
>
> The problems you cite are not the fault of JAI per se, but of the jpeg
> reader. If the reader is capable of tiling the image, then JAI will
> make
> use of it. Unfortunately the old-style codec-based jpeg reader that
> is supplied with JAI is incapable of tiling the image on read, thus the
> problems you saw.
>
> So try "imageread" instead of "fileload" to use the new IIO plugin, and
> see if that works easier.
>
> -Bob
>
> -----------cut here-----------clip & save-----------valuable
> coupon-----------
>
> On Jun 9, 2007, at 10:28 AM, martinrleon wrote:
>
>>
>> Give it up! I tried and tried to find a way to create a thumbnail
>> using JAI
>> and there seems to be a fundamental flaw with JAI - there doesn't
>> seem to be
>> a way to perform any JAI operations that don't attempt to load the
>> entire
>> image into memory, requiring ridiculous amounts of memory. Every JAI
>> operation that I could think of or could find reference to causes
>> the image
>> to be loaded. On the Sun Java forums for JAI they recommend
>> setting the
>> TileCache memory via TileCache.setMemoryCapacity and
>> TileCach.setMemoryThreshold. all to no avail. So I finally gave up
>> on using
>> JAI to create thumbnails.
>>
>> I found that the same thing occurs with the Java AWT image classes,
>> which
>> cause the entire image to be loaded in order to even get the image
>> dimension
>> information such as width and height, which you need in order to
>> figure out
>> how to scale or subsample the original image in order to be able to
>> generate
>> a smaller version. As I was researching this, I found some advice
>> in a Sun
>> Java forum and came up with the code below which uses ImageIO to
>> create
>> thumbnails. Using ImageIO you can get the image dimension information
>> without having to render the image in memory. With that
>> information you can
>> subsample the image data, yielding a much smaller rendered image!
>> The code
>> below demonstrates this. I hope this helps someone, it's taken me
>> days to
>> figure this out.
>>
>> My approach involves using an ImageIO ImageReader to get the dimension
>> information so I can compute how to subsample the source image. I
>> subsample
>> a slightly larger number (25%) of pixels into an intermediate
>> thumbnail
>> image that is slightly larger than the desired thumbnail size so I
>> can use
>> interpolation in order to get a better quality thumbnail image.
>> From the
>> intermediate thumbnail image I render down to the final thumbnail
>> image and
>> store it in a file.
>>
>> This worked with a 40MB PNG file and a 7MB JPG file. I also tried
>> TIFF but
>> there doesn't seem to be an image reader for TIFF in the 1.4.2 Java
>> that I
>> am working with. I'm assuming there is a way to add TIFF support,
>> but I
>> don't really need to support TIFF.
>>
>> import java.awt.Frame;
>> import java.awt.Graphics2D;
>> import java.awt.RenderingHints;
>> import java.awt.image.BufferedImage;
>> import java.io.BufferedInputStream;
>> import java.io.BufferedOutputStream;
>> import java.io.File;
>> import java.io.FileInputStream;
>> import java.io.FileOutputStream;
>>
>> import javax.imageio.ImageIO;
>> import javax.imageio.ImageReadParam;
>> import javax.imageio.ImageReader;
>> import javax.imageio.stream.ImageInputStream;
>>
>> import com.sun.image.codec.jpeg.JPEGCodec;
>> import com.sun.image.codec.jpeg.JPEGEncodeParam;
>> import com.sun.image.codec.jpeg.JPEGImageEncoder;
>>
>> /*
>> * Created on Jun 9, 2007
>> */
>>
>> public class TestIIOthumbnails {
>>
>> private final static String[] knownFormats;
>>
>> static {
>> knownFormats = ImageIO.getReaderFormatNames();
>> for ( int x = 0 ; x < knownFormats.length ; x++ ) {
>> knownFormats[x] = '.' + knownFormats[x].toLowerCase();
>> }
>> }
>>
>> public static void main( String[] args ) {
>> int thumbnailDimension = 300;
>> float thumbnailQuality = 0.5f;
>>
>> try {
>>
>> String[] fileNames = { "PIA03231.JPG" , "PIA03241.JPG" ,
>> "PIA08814.JPG" , "PIA09201.JPG" , "PIA09202.JPG" ,
>> "PIA09203.JPG" , "PIA09205.JPG" , "PIA09207.JPG" ,
>> "PIA09259.JPG" , "large4.png" , "large3.png" ,
>> "large2.png" , "large.png" , "marbles.tif" ,
>> "xing_t24.tif" };
>>
>> for ( int x = 0 ; x < fileNames.length ; x++ ) {
>> final File inputFile = new File( fileNames[x] );
>> if ( !inputFile.exists() ) {
>> System.out.println( "Unable to locate file: " +
>> inputFile.getCanonicalPath() );
>> continue;
>> }
>>
>> final File thumbnailFile = makeThumbnailFile
>> ( inputFile ,
>> thumbnailDimension , thumbnailQuality );
>> if ( thumbnailFile != null && thumbnailFile.exists
>> () ) {
>> System.out.println
>> ( thumbnailFile.getCanonicalPath() + "
>> succesfully created" );
>> }
>> else {
>> System.out.println( "Unable to create thumbnail
>> for " +
>> inputFile.getCanonicalPath() );
>> }
>> }
>> System.out.println( "Done." );
>> }
>> catch( Exception e ) {
>> CommonLib.logException( e , CommonLib.notOnServer() );
>> }
>> }
>>
>> private static File makeThumbnailFile( File inputFile , int
>> thumbnailDimension , float thumbnailQuality ) {
>>
>> File response = null;
>>
>> try {
>> if ( inputFile == null ) {
>> System.out.println( "Input file is null" );
>> return response;
>> }
>> if ( !inputFile.exists() ) {
>> System.out.println( "Input file does not exist: " +
>> inputFile.getName() );
>> return response;
>> }
>> if ( !isKnownFormat( inputFile.toString() ) ) {
>> System.out.println( "Unsupported file format: " +
>> inputFile.getName() );
>> return response;
>> }
>>
>> final Frame frame = new Frame();
>> frame.addNotify();
>>
>> final String fileSuffix = knownAliases
>> ( inputFile.getName()
>> ).substring( 1 );
>>
>> final ImageReader imgReader = (ImageReader)
>> ImageIO.getImageReadersBySuffix( fileSuffix ).next();
>>
>> final ImageInputStream bufferedInput =
>> ImageIO.createImageInputStream( new BufferedInputStream(
>> new FileInputStream( inputFile ) ) );
>>
>> imgReader.setInput( bufferedInput );
>>
>> int imgHeight = imgReader.getHeight( 0 );
>> int imgWidth = imgReader.getWidth( 0 );
>>
>> double imageRatio = (double) imgWidth / (double)
>> imgHeight;
>> int thumbnailHeight = thumbnailDimension;
>> int thumbnailWidth = thumbnailDimension;
>>
>> if ( imageRatio > 1.0d ) {
>> thumbnailHeight = (int) ( thumbnailDimension /
>> imageRatio );
>> }
>> else {
>> thumbnailWidth = (int) ( thumbnailDimension *
>> imageRatio );
>> }
>>
>> int longEdge = ( Math.max( imgHeight , imgWidth ) );
>> int tempThumbnailEdge = (int) ( (float)
>> thumbnailDimension *
>> 1.25f );
>> int subSample = (int) ( (float) longEdge / (float)
>> tempThumbnailEdge );
>>
>> final ImageReadParam readParam =
>> imgReader.getDefaultReadParam();
>> if ( subSample > 1 ) {
>> readParam.setSourceSubsampling( subSample ,
>> subSample , 0 ,
>> 0 );
>> }
>>
>> final BufferedImage tempThumbnailImage = imgReader.read
>> ( 0 ,
>> readParam );
>>
>> final BufferedImage thumbnailImage = new BufferedImage(
>> thumbnailWidth , thumbnailHeight ,
>> BufferedImage.TYPE_INT_RGB );
>> final Graphics2D graphics2D =
>> thumbnailImage.createGraphics();
>> graphics2D
>> .setRenderingHint
>> ( RenderingHints.KEY_INTERPOLATION ,
>> RenderingHints.VALUE_INTERPOLATION_BILINEAR );
>> graphics2D.drawImage( tempThumbnailImage , 0 , 0 ,
>> thumbnailWidth , thumbnailHeight , frame );
>>
>> final String thumbnailFileName = getThumbnailFileName(
>> inputFile.getCanonicalPath() );
>> final File thumbnailFile = new File( thumbnailFileName );
>> final BufferedOutputStream thumbnailOut = new
>> BufferedOutputStream(
>> ( new FileOutputStream( thumbnailFile ) ) ,
>> 4092 );
>> final JPEGImageEncoder encoder =
>> JPEGCodec.createJPEGEncoder(
>> thumbnailOut );
>> final JPEGEncodeParam encoderParam =
>> encoder.getDefaultJPEGEncodeParam( thumbnailImage );
>> encoderParam.setQuality( thumbnailQuality , false );
>> encoder.setJPEGEncodeParam( encoderParam );
>> encoder.encode( thumbnailImage );
>> thumbnailOut.close();
>>
>> // Dispose of AWT components
>> graphics2D.dispose();
>> frame.dispose();
>>
>> response = thumbnailFile;
>> }
>> catch( Exception e ) {
>> e.printStackTrace();
>> }
>> return response;
>> }
>>
>> private static boolean isKnownFormat( String fileName ) {
>> boolean response = false;
>>
>> if ( fileName == null || fileName.length() == 0 ) {
>> return response;
>> }
>> int extensionPosition = fileName.lastIndexOf( '.' );
>>
>> if ( extensionPosition == -1 ) return response;
>>
>> final String extension = knownAliases( fileName.substring(
>> extensionPosition ).toLowerCase() );
>>
>> for ( int x = 0 ; x < knownFormats.length ; x++ ) {
>> if ( extension.equals( knownFormats[x] ) ) {
>> return true;
>> }
>> }
>>
>> return response;
>> }
>>
>> private static String knownAliases( String fileName ) {
>> final String extension = fileName.substring
>> ( fileName.lastIndexOf(
>> '.' ) ).toLowerCase();
>> if ( extension.equals( ".jpg" ) ) return ".jpeg";
>> if ( extension.equals( ".jpe" ) ) return ".jpeg";
>> if ( extension.equals( ".tif" ) ) return ".tiff";
>> return extension;
>> }
>>
>> private static String getThumbnailFileName( String
>> attachmentName ) {
>> String result = null;
>> int dotIndex = 0;
>>
>> // Get the position of the . before the extension
>> dotIndex = attachmentName.lastIndexOf( "." );
>> // Get the extension of the current file
>> final String extension = attachmentName.substring( dotIndex
>> + 1 );
>> // Get the file name without the extension
>> result = attachmentName.substring( 0 , dotIndex );
>> // Build the thumbnail file name
>> result = result + "_thumb_" + extension + ".jpg";
>>
>> return result;
>> }
>> }
>>
>> --
>> View this message in context: http://www.nabble.com/using-JAI-to-
>> create-a-thumbnail-as-a-JPEG-tf3701670.html#a11042093
>> Sent from the JAI Projects - Interest mailing list archive at
>> Nabble.com.
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: interest-unsubscribe@jai.dev.java.net
>> For additional commands, e-mail: interest-help@jai.dev.java.net
>>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: interest-unsubscribe@jai.dev.java.net
> For additional commands, e-mail: interest-help@jai.dev.java.net
>
>
>

--
View this message in context: http://www.nabble.com/using-JAI-to-create-a-thumbnail-as-a-JPEG-tf3701670.html#a11046982
Sent from the JAI Projects - Interest mailing list archive at Nabble.com.

---------------------------------------------------------------------
To unsubscribe, e-mail: interest-unsubscribe@jai.dev.java.net
For additional commands, e-mail: interest-help@jai.dev.java.net


Nidel, Mike
RE: [JAI] using JAI to create a thumbnail as a JPEG
Posted: Jun 11, 2007 6:00 AM   in response to: martinrleon
  Click to reply to this thread Reply

the "imageread" operator is a way to use a JAI operator to wrap
the functionality of the ImageIO API. It is included in the JAI
ImageIO tools package (http://jai-imageio.dev.java.net).

JAI is not strictly a "newer" API than ImageIO, in fact JAI was
around before ImageIO was a part of the J2SE distribution (1.4).
JAI is really an image processing framework, whereas ImageIO is
for reading and writing images. You can read an image with ImageIO,
process it with JAI, and write it again with ImageIO.

Now the JAI ImageIO Tools libraries are perhaps newer than ImageIO.
These are a set of plugins to provide the functionality that is
also provided in the JAI codecs, but accessible through the standard
ImageIO API. Check the link above for more info; it might be that
the JPEG reader in the JAI ImageIO Tools bundle works better for what
you want. However, it might also not be the case.

The bottom line is if you are reading a large image to generate
a thumbnail of it, and the reader is incapable of reading the image
in manageable chunks, then you will run into the memory problems
you encountered. At that point, you may need to find a new image
reader.

Mike


> -----Original Message-----
> From: martinrleon [mailto:martinrleon@yahoo.com]
> Sent: Sunday, June 10, 2007 5:11 AM
> To: interest@jai.dev.java.net
> Subject: Re: [JAI] using JAI to create a thumbnail as a JPEG
>
>
> Thanks for your response.
>
> I can't find any documentation for the "imageread" operator.
> Is it bundled with the standard 1.4 SE distribution or is it
> something I have to add? If so, how do I add the ImageIO
> plugin to my JAI configuration and where can I find
> documentation for it?
>
> Thanks again for your response, I was incredulous about a
> newer API (JAI) not being able to do what an older one could
> do (ImageIO) - I figured they didn't want to make the effort
> when another API could already provide the functionality.
>
>
> Bob Deen wrote:
> >
> > Did you try the imageread operator in JAI, which wraps
> around Image I/O?
> >
> > The problems you cite are not the fault of JAI per se, but
> of the jpeg
> > reader. If the reader is capable of tiling the image, then
> JAI will
> > make use of it. Unfortunately the old-style codec-based
> jpeg reader
> > that is supplied with JAI is incapable of tiling the image on read,
> > thus the problems you saw.
> >
> > So try "imageread" instead of "fileload" to use the new IIO plugin,
> > and see if that works easier.
> >
> > -Bob
> >
> > -----------cut here-----------clip & save-----------valuable
> > coupon-----------
> >
> > On Jun 9, 2007, at 10:28 AM, martinrleon wrote:
> >
> >>
> >> Give it up! I tried and tried to find a way to create a thumbnail
> >> using JAI and there seems to be a fundamental flaw with
> JAI - there
> >> doesn't seem to be a way to perform any JAI operations that don't
> >> attempt to load the entire image into memory, requiring ridiculous
> >> amounts of memory. Every JAI operation that I could think of or
> >> could find reference to causes the image to be loaded. On the Sun
> >> Java forums for JAI they recommend setting the TileCache
> memory via
> >> TileCache.setMemoryCapacity and
> TileCach.setMemoryThreshold. all to
> >> no avail. So I finally gave up on using JAI to create thumbnails.
> >>
> >> I found that the same thing occurs with the Java AWT image
> classes,
> >> which cause the entire image to be loaded in order to even get the
> >> image dimension information such as width and height,
> which you need
> >> in order to figure out how to scale or subsample the
> original image
> >> in order to be able to generate a smaller version. As I was
> >> researching this, I found some advice in a Sun Java forum
> and came up
> >> with the code below which uses ImageIO to create
> thumbnails. Using
> >> ImageIO you can get the image dimension information
> without having to
> >> render the image in memory. With that information you can
> >> subsample the image data, yielding a much smaller rendered
> image!
> >> The code
> >> below demonstrates this. I hope this helps someone, it's taken me
> >> days to figure this out.
> >>
> >> My approach involves using an ImageIO ImageReader to get the
> >> dimension information so I can compute how to subsample the source
> >> image. I subsample a slightly larger number (25%) of
> pixels into an
> >> intermediate thumbnail image that is slightly larger than
> the desired
> >> thumbnail size so I can use
> >> interpolation in order to get a better quality thumbnail image.
> >> From the
> >> intermediate thumbnail image I render down to the final thumbnail
> >> image and store it in a file.
> >>
> >> This worked with a 40MB PNG file and a 7MB JPG file. I also tried
> >> TIFF but there doesn't seem to be an image reader for TIFF in the
> >> 1.4.2 Java that I am working with. I'm assuming there is a way to
> >> add TIFF support, but I don't really need to support TIFF.
> >>
> >> import java.awt.Frame;
> >> import java.awt.Graphics2D;
> >> import java.awt.RenderingHints;
> >> import java.awt.image.BufferedImage;
> >> import java.io.BufferedInputStream;
> >> import java.io.BufferedOutputStream;
> >> import java.io.File;
> >> import java.io.FileInputStream;
> >> import java.io.FileOutputStream;
> >>
> >> import javax.imageio.ImageIO;
> >> import javax.imageio.ImageReadParam;
> >> import javax.imageio.ImageReader;
> >> import javax.imageio.stream.ImageInputStream;
> >>
> >> import com.sun.image.codec.jpeg.JPEGCodec;
> >> import com.sun.image.codec.jpeg.JPEGEncodeParam;
> >> import com.sun.image.codec.jpeg.JPEGImageEncoder;
> >>
> >> /*
> >> * Created on Jun 9, 2007
> >> */
> >>
> >> public class TestIIOthumbnails {
> >>
> >> private final static String[] knownFormats;
> >>
> >> static {
> >> knownFormats = ImageIO.getReaderFormatNames();
> >> for ( int x = 0 ; x < knownFormats.length ; x++ ) {
> >> knownFormats[x] = '.' + knownFormats[x].toLowerCase();
> >> }
> >> }
> >>
> >> public static void main( String[] args ) {
> >> int thumbnailDimension = 300;
> >> float thumbnailQuality = 0.5f;
> >>
> >> try {
> >>
> >> String[] fileNames = { "PIA03231.JPG" ,
> "PIA03241.JPG" ,
> >> "PIA08814.JPG" , "PIA09201.JPG" , "PIA09202.JPG" ,
> >> "PIA09203.JPG" , "PIA09205.JPG" ,
> "PIA09207.JPG"
> >> , "PIA09259.JPG" , "large4.png" , "large3.png" ,
> >> "large2.png" , "large.png" , "marbles.tif" ,
> >> "xing_t24.tif" };
> >>
> >> for ( int x = 0 ; x < fileNames.length ; x++ ) {
> >> final File inputFile = new File( fileNames[x] );
> >> if ( !inputFile.exists() ) {
> >> System.out.println( "Unable to locate file: " +
> >> inputFile.getCanonicalPath() );
> >> continue;
> >> }
> >>
> >> final File thumbnailFile = makeThumbnailFile (
> >> inputFile , thumbnailDimension , thumbnailQuality );
> >> if ( thumbnailFile != null && thumbnailFile.exists
> >> () ) {
> >> System.out.println (
> >> thumbnailFile.getCanonicalPath() + "
> >> succesfully created" );
> >> }
> >> else {
> >> System.out.println( "Unable to create
> thumbnail
> >> for " +
> >> inputFile.getCanonicalPath() );
> >> }
> >> }
> >> System.out.println( "Done." );
> >> }
> >> catch( Exception e ) {
> >> CommonLib.logException( e , CommonLib.notOnServer() );
> >> }
> >> }
> >>
> >> private static File makeThumbnailFile( File inputFile , int
> >> thumbnailDimension , float thumbnailQuality ) {
> >>
> >> File response = null;
> >>
> >> try {
> >> if ( inputFile == null ) {
> >> System.out.println( "Input file is null" );
> >> return response;
> >> }
> >> if ( !inputFile.exists() ) {
> >> System.out.println( "Input file does not exist: " +
> >> inputFile.getName() );
> >> return response;
> >> }
> >> if ( !isKnownFormat( inputFile.toString() ) ) {
> >> System.out.println( "Unsupported file format: " +
> >> inputFile.getName() );
> >> return response;
> >> }
> >>
> >> final Frame frame = new Frame();
> >> frame.addNotify();
> >>
> >> final String fileSuffix = knownAliases (
> >> inputFile.getName() ).substring( 1 );
> >>
> >> final ImageReader imgReader = (ImageReader)
> >> ImageIO.getImageReadersBySuffix( fileSuffix ).next();
> >>
> >> final ImageInputStream bufferedInput =
> >> ImageIO.createImageInputStream( new BufferedInputStream(
> >> new FileInputStream( inputFile ) ) );
> >>
> >> imgReader.setInput( bufferedInput );
> >>
> >> int imgHeight = imgReader.getHeight( 0 );
> >> int imgWidth = imgReader.getWidth( 0 );
> >>
> >> double imageRatio = (double) imgWidth / (double)
> >> imgHeight;
> >> int thumbnailHeight = thumbnailDimension;
> >> int thumbnailWidth = thumbnailDimension;
> >>
> >> if ( imageRatio > 1.0d ) {
> >> thumbnailHeight = (int) ( thumbnailDimension /
> >> imageRatio );
> >> }
> >> else {
> >> thumbnailWidth = (int) ( thumbnailDimension *
> >> imageRatio );
> >> }
> >>
> >> int longEdge = ( Math.max( imgHeight , imgWidth ) );
> >> int tempThumbnailEdge = (int) ( (float)
> >> thumbnailDimension * 1.25f );
> >> int subSample = (int) ( (float) longEdge / (float)
> >> tempThumbnailEdge );
> >>
> >> final ImageReadParam readParam =
> >> imgReader.getDefaultReadParam();
> >> if ( subSample > 1 ) {
> >> readParam.setSourceSubsampling( subSample
> , subSample
> >> , 0 , 0 );
> >> }
> >>
> >> final BufferedImage tempThumbnailImage =
> imgReader.read (
> >> 0 , readParam );
> >>
> >> final BufferedImage thumbnailImage = new
> BufferedImage(
> >> thumbnailWidth , thumbnailHeight ,
> >> BufferedImage.TYPE_INT_RGB );
> >> final Graphics2D graphics2D =
> >> thumbnailImage.createGraphics();
> >> graphics2D
> >> .setRenderingHint (
> >> RenderingHints.KEY_INTERPOLATION ,
> >> RenderingHints.VALUE_INTERPOLATION_BILINEAR );
> >> graphics2D.drawImage( tempThumbnailImage , 0 , 0 ,
> >> thumbnailWidth , thumbnailHeight , frame );
> >>
> >> final String thumbnailFileName = getThumbnailFileName(
> >> inputFile.getCanonicalPath() );
> >> final File thumbnailFile = new File(
> thumbnailFileName );
> >> final BufferedOutputStream thumbnailOut = new
> >> BufferedOutputStream(
> >> ( new FileOutputStream( thumbnailFile ) ) ,
> >> 4092 );
> >> final JPEGImageEncoder encoder =
> >> JPEGCodec.createJPEGEncoder( thumbnailOut );
> >> final JPEGEncodeParam encoderParam =
> >> encoder.getDefaultJPEGEncodeParam( thumbnailImage );
> >> encoderParam.setQuality( thumbnailQuality , false );
> >> encoder.setJPEGEncodeParam( encoderParam );
> >> encoder.encode( thumbnailImage );
> >> thumbnailOut.close();
> >>
> >> // Dispose of AWT components
> >> graphics2D.dispose();
> >> frame.dispose();
> >>
> >> response = thumbnailFile;
> >> }
> >> catch( Exception e ) {
> >> e.printStackTrace();
> >> }
> >> return response;
> >> }
> >>
> >> private static boolean isKnownFormat( String fileName ) {
> >> boolean response = false;
> >>
> >> if ( fileName == null || fileName.length() == 0 ) {
> >> return response;
> >> }
> >> int extensionPosition = fileName.lastIndexOf( '.' );
> >>
> >> if ( extensionPosition == -1 ) return response;
> >>
> >> final String extension = knownAliases( fileName.substring(
> >> extensionPosition ).toLowerCase() );
> >>
> >> for ( int x = 0 ; x < knownFormats.length ; x++ ) {
> >> if ( extension.equals( knownFormats[x] ) ) {
> >> return true;
> >> }
> >> }
> >>
> >> return response;
> >> }
> >>
> >> private static String knownAliases( String fileName ) {
> >> final String extension = fileName.substring (
> >> fileName.lastIndexOf( '.' ) ).toLowerCase();
> >> if ( extension.equals( ".jpg" ) ) return ".jpeg";
> >> if ( extension.equals( ".jpe" ) ) return ".jpeg";
> >> if ( extension.equals( ".tif" ) ) return ".tiff";
> >> return extension;
> >> }
> >>
> >> private static String getThumbnailFileName( String
> attachmentName
> >> ) {
> >> String result = null;
> >> int dotIndex = 0;
> >>
> >> // Get the position of the . before the extension
> >> dotIndex = attachmentName.lastIndexOf( "." );
> >> // Get the extension of the current file
> >> final String extension = attachmentName.substring( dotIndex
> >> + 1 );
> >> // Get the file name without the extension
> >> result = attachmentName.substring( 0 , dotIndex );
> >> // Build the thumbnail file name
> >> result = result + "_thumb_" + extension + ".jpg";
> >>
> >> return result;
> >> }
> >> }
> >>
> >> --
> >> View this message in context: http://www.nabble.com/using-JAI-to-
> >> create-a-thumbnail-as-a-JPEG-tf3701670.html#a11042093
> >> Sent from the JAI Projects - Interest mailing list archive at
> >> Nabble.com.
> >>
> >>
> ---------------------------------------------------------------------
> >> To unsubscribe, e-mail: interest-unsubscribe@jai.dev.java.net
> >> For additional commands, e-mail: interest-help@jai.dev.java.net
> >>
> >
> >
> ---------------------------------------------------------------------
> > To unsubscribe, e-mail: interest-unsubscribe@jai.dev.java.net
> > For additional commands, e-mail: interest-help@jai.dev.java.net
> >
> >
> >
>
> --
> View this message in context:
> http://www.nabble.com/using-JAI-to-create-a-thumbnail-as-a-JPE
> G-tf3701670.html#a11046982
> Sent from the JAI Projects - Interest mailing list archive at
> Nabble.com.
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: interest-unsubscribe@jai.dev.java.net
> For additional commands, e-mail: interest-help@jai.dev.java.net
>
>

---------------------------------------------------------------------
To unsubscribe, e-mail: interest-unsubscribe@jai.dev.java.net
For additional commands, e-mail: interest-help@jai.dev.java.net


fred34

Posts: 128
Re: RE: [JAI] using JAI to create a thumbnail as a JPEG
Posted: Jun 11, 2007 6:24 AM   in response to: Nidel, Mike
 
  Click to reply to this thread Reply

Try using the ImageIO reader sub sampling feature. This instructs the readers to only read every x pixels horzontally or y pixels vertically. For making thumbnails this would seem the obvious answer. If you set the x and y subsampling to 2 then the returned image will be half-size in each dimension (so 1/4 of the memory). This is done during the decode, it is not a scaling operation done afterwards so it should reduce the memory requirements a lot. You can set the subsampling in the ImageReadParam for the decoder.

Brian Burkhalter
Re: RE: [JAI] using JAI to create a thumbnail as a JPEG
Posted: Jun 11, 2007 5:41 PM   in response to: fred34
  Click to reply to this thread Reply

If the JAI Image I/O Tools JPEG reader is bsing used this won't help. Per the
javadoc with respect to JPEG and PNG:

"All subsampling and sub-banding is performed in memory, however, so if either
is required, use of the core JPEG plug-in might be preferable."

On Mon, 11 Jun 2007, jai-interest@javadesktop.org wrote:

> Try using the ImageIO reader sub sampling feature. This instructs the readers to only read every x pixels horzontally or y pixels vertically. For making thumbnails this would seem the obvious answer. If you set the x and y subsampling to 2 then the returned image will be half-size in each dimension (so 1/4 of the memory). This is done during the decode, it is not a scaling operation done afterwards so it should reduce the memory requirements a lot. You can set the subsampling in the ImageReadParam for the decoder.
> [Message sent by forum member 'fred34' (fred34)]
>
> http://forums.java.net/jive/thread.jspa?messageID=221478
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: interest-unsubscribe@jai.dev.java.net
> For additional commands, e-mail: interest-help@jai.dev.java.net
>
>

----------------
Brian Burkhalter
Java Media, Imaging, and Graphics
Sun Microsystems, Inc.

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
This email message is for the sole use of the intended recipient(s)
and may contain confidential and privileged information. Any
unauthorized review, use, disclosure or distribution is prohibited.
If you are not the intended recipient, please contact the sender by
reply email and destroy all copies of the original message.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

---------------------------------------------------------------------
To unsubscribe, e-mail: interest-unsubscribe@jai.dev.java.net
For additional commands, e-mail: interest-help@jai.dev.java.net


martinrleon
[JAI] RE: using JAI to create a thumbnail as a JPEG
Posted: Jun 11, 2007 7:15 PM   in response to: Nidel, Mike
  Click to reply to this thread Reply


Mike,

Thank you for the clarification and the URL.

I was able to accomplish what I needed to by using the ImageReader class in
ImageIO but was curious whether JAI could do it, I guess not without relying
on ImageIO.

Thanks to your URL reference I have a choice of going with JAI and adding
support for additional file formats. I really appreciate that.

Martin


Nidel, Mike wrote:
>
> the "imageread" operator is a way to use a JAI operator to wrap
> the functionality of the ImageIO API. It is included in the JAI
> ImageIO tools package (http://jai-imageio.dev.java.net).
>
> JAI is not strictly a "newer" API than ImageIO, in fact JAI was
> around before ImageIO was a part of the J2SE distribution (1.4).
> JAI is really an image processing framework, whereas ImageIO is
> for reading and writing images. You can read an image with ImageIO,
> process it with JAI, and write it again with ImageIO.
>
> Now the JAI ImageIO Tools libraries are perhaps newer than ImageIO.
> These are a set of plugins to provide the functionality that is
> also provided in the JAI codecs, but accessible through the standard
> ImageIO API. Check the link above for more info; it might be that
> the JPEG reader in the JAI ImageIO Tools bundle works better for what
> you want. However, it might also not be the case.
>
> The bottom line is if you are reading a large image to generate
> a thumbnail of it, and the reader is incapable of reading the image
> in manageable chunks, then you will run into the memory problems
> you encountered. At that point, you may need to find a new image
> reader.
>
> Mike
>
>

--
View this message in context: http://www.nabble.com/using-JAI-to-create-a-thumbnail-as-a-JPEG-tf3701670.html#a11071881
Sent from the JAI Projects - Interest mailing list archive at Nabble.com.

---------------------------------------------------------------------
To unsubscribe, e-mail: interest-unsubscribe@jai.dev.java.net
For additional commands, e-mail: interest-help@jai.dev.java.net


Brian Burkhalter
Re: [JAI] RE: using JAI to create a thumbnail as a JPEG
Posted: Jun 11, 2007 9:19 PM   in response to: martinrleon
  Click to reply to this thread Reply

The codecs in JAI were provided as a convenience to users and were never a
formal API. JAI is an API for image processing. Image I/O is an API for just
that. JAI Image I/O Tools provides support for formats not handled by Java SE
Image I/O.

Brian

On Mon, 11 Jun 2007, martinrleon wrote:

>
> Mike,
>
> Thank you for the clarification and the URL.
>
> I was able to accomplish what I needed to by using the ImageReader class in
> ImageIO but was curious whether JAI could do it, I guess not without relying
> on ImageIO.
>
> Thanks to your URL reference I have a choice of going with JAI and adding
> support for additional file formats. I really appreciate that.
>
> Martin
>
>
> Nidel, Mike wrote:
>>
>> the "imageread" operator is a way to use a JAI operator to wrap
>> the functionality of the ImageIO API. It is included in the JAI
>> ImageIO tools package (http://jai-imageio.dev.java.net).
>>
>> JAI is not strictly a "newer" API than ImageIO, in fact JAI was
>> around before ImageIO was a part of the J2SE distribution (1.4).
>> JAI is really an image processing framework, whereas ImageIO is
>> for reading and writing images. You can read an image with ImageIO,
>> process it with JAI, and write it again with ImageIO.
>>
>> Now the JAI ImageIO Tools libraries are perhaps newer than ImageIO.
>> These are a set of plugins to provide the functionality that is
>> also provided in the JAI codecs, but accessible through the standard
>> ImageIO API. Check the link above for more info; it might be that
>> the JPEG reader in the JAI ImageIO Tools bundle works better for what
>> you want. However, it might also not be the case.
>>
>> The bottom line is if you are reading a large image to generate
>> a thumbnail of it, and the reader is incapable of reading the image
>> in manageable chunks, then you will run into the memory problems
>> you encountered. At that point, you may need to find a new image
>> reader.
>>
>> Mike
>>
>>
>
> --
> View this message in context: http://www.nabble.com/using-JAI-to-create-a-thumbnail-as-a-JPEG-tf3701670.html#a11071881
> Sent from the JAI Projects - Interest mailing list archive at Nabble.com.
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: interest-unsubscribe@jai.dev.java.net
> For additional commands, e-mail: interest-help@jai.dev.java.net
>
>

----------------
Brian Burkhalter
Java Media, Imaging, and Graphics
Sun Microsystems, Inc.

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
This email message is for the sole use of the intended recipient(s)
and may contain confidential and privileged information. Any
unauthorized review, use, disclosure or distribution is prohibited.
If you are not the intended recipient, please contact the sender by
reply email and destroy all copies of the original message.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

---------------------------------------------------------------------
To unsubscribe, e-mail: interest-unsubscribe@jai.dev.java.net
For additional commands, e-mail: interest-help@jai.dev.java.net


Brian Burkhalter
Re: [JAI] using JAI to create a thumbnail as a JPEG
Posted: Jun 11, 2007 5:46 PM   in response to: martinrleon
  Click to reply to this thread Reply

As Mike pointed out the JAI operations have nothing to do with this.
Operations use whatever layout you happen to have and if the decoder or reader
can only return an untiled image then that is what is used.

Note also that subsampling will give a lousy result if the image has any
significant high frequency content as the subsampling will induce aliasing. In
terms of quality what seems to produce the best result is SubsampleAverage.
But as mentioned if the source image can only be decoded monolithically then
you have to have the memory to handle it.

On Sat, 9 Jun 2007, martinrleon wrote:

> Give it up! I tried and tried to find a way to create a thumbnail using JAI
> and there seems to be a fundamental flaw with JAI - there doesn't seem to be
> a way to perform any JAI operations that don't attempt to load the entire
> image into memory, requiring ridiculous amounts of memory. Every JAI
> operation that I could think of or could find reference to causes the image
> to be loaded. On the Sun Java forums for JAI they recommend setting the
> TileCache memory via TileCache.setMemoryCapacity and
> TileCach.setMemoryThreshold. all to no avail. So I finally gave up on using
> JAI to create thumbnails.
>
> I found that the same thing occurs with the Java AWT image classes, which
> cause the entire image to be loaded in order to even get the image dimension
> information such as width and height, which you need in order to figure out
> how to scale or subsample the original image in order to be able to generate
> a smaller version. As I was researching this, I found some advice in a Sun
> Java forum and came up with the code below which uses ImageIO to create
> thumbnails. Using ImageIO you can get the image dimension information
> without having to render the image in memory. With that information you can
> subsample the image data, yielding a much smaller rendered image! The code
> below demonstrates this. I hope this helps someone, it's taken me days to
> figure this out.
>
> My approach involves using an ImageIO ImageReader to get the dimension
> information so I can compute how to subsample the source image. I subsample
> a slightly larger number (25%) of pixels into an intermediate thumbnail
> image that is slightly larger than the desired thumbnail size so I can use
> interpolation in order to get a better quality thumbnail image. From the
> intermediate thumbnail image I render down to the final thumbnail image and
> store it in a file.
>
> This worked with a 40MB PNG file and a 7MB JPG file. I also tried TIFF but
> there doesn't seem to be an image reader for TIFF in the 1.4.2 Java that I
> am working with. I'm assuming there is a way to add TIFF support, but I
> don't really need to support TIFF.
>
> import java.awt.Frame;
> import java.awt.Graphics2D;
> import java.awt.RenderingHints;
> import java.awt.image.BufferedImage;
> import java.io.BufferedInputStream;
> import java.io.BufferedOutputStream;
> import java.io.File;
> import java.io.FileInputStream;
> import java.io.FileOutputStream;
>
> import javax.imageio.ImageIO;
> import javax.imageio.ImageReadParam;
> import javax.imageio.ImageReader;
> import javax.imageio.stream.ImageInputStream;
>
> import com.sun.image.codec.jpeg.JPEGCodec;
> import com.sun.image.codec.jpeg.JPEGEncodeParam;
> import com.sun.image.codec.jpeg.JPEGImageEncoder;
>
> /*
> * Created on Jun 9, 2007
> */
>
> public class TestIIOthumbnails {
>
> private final static String[] knownFormats;
>
> static {
> knownFormats = ImageIO.getReaderFormatNames();
> for ( int x = 0 ; x < knownFormats.length ; x++ ) {
> knownFormats[x] = '.' + knownFormats[x].toLowerCase();
> }
> }
>
> public static void main( String[] args ) {
> int thumbnailDimension = 300;
> float thumbnailQuality = 0.5f;
>
> try {
>
> String[] fileNames = { "PIA03231.JPG" , "PIA03241.JPG" ,
> "PIA08814.JPG" , "PIA09201.JPG" , "PIA09202.JPG" ,
> "PIA09203.JPG" , "PIA09205.JPG" , "PIA09207.JPG" ,
> "PIA09259.JPG" , "large4.png" , "large3.png" ,
> "large2.png" , "large.png" , "marbles.tif" ,
> "xing_t24.tif" };
>
> for ( int x = 0 ; x < fileNames.length ; x++ ) {
> final File inputFile = new File( fileNames[x] );
> if ( !inputFile.exists() ) {
> System.out.println( "Unable to locate file: " +
> inputFile.getCanonicalPath() );
> continue;
> }
>
> final File thumbnailFile = makeThumbnailFile( inputFile ,
> thumbnailDimension , thumbnailQuality );
> if ( thumbnailFile != null && thumbnailFile.exists() ) {
> System.out.println( thumbnailFile.getCanonicalPath() + "
> succesfully created" );
> }
> else {
> System.out.println( "Unable to create thumbnail for " +
> inputFile.getCanonicalPath() );
> }
> }
> System.out.println( "Done." );
> }
> catch( Exception e ) {
> CommonLib.logException( e , CommonLib.notOnServer() );
> }
> }
>
> private static File makeThumbnailFile( File inputFile , int
> thumbnailDimension , float thumbnailQuality ) {
>
> File response = null;
>
> try {
> if ( inputFile == null ) {
> System.out.println( "Input file is null" );
> return response;
> }
> if ( !inputFile.exists() ) {
> System.out.println( "Input file does not exist: " +
> inputFile.getName() );
> return response;
> }
> if ( !isKnownFormat( inputFile.toString() ) ) {
> System.out.println( "Unsupported file format: " +
> inputFile.getName() );
> return response;
> }
>
> final Frame frame = new Frame();
> frame.addNotify();
>
> final String fileSuffix = knownAliases( inputFile.getName()
> ).substring( 1 );
>
> final ImageReader imgReader = (ImageReader)
> ImageIO.getImageReadersBySuffix( fileSuffix ).next();
>
> final ImageInputStream bufferedInput =
> ImageIO.createImageInputStream( new BufferedInputStream(
> new FileInputStream( inputFile ) ) );
>
> imgReader.setInput( bufferedInput );
>
> int imgHeight = imgReader.getHeight( 0 );
> int imgWidth = imgReader.getWidth( 0 );
>
> double imageRatio = (double) imgWidth / (double) imgHeight;
> int thumbnailHeight = thumbnailDimension;
> int thumbnailWidth = thumbnailDimension;
>
> if ( imageRatio > 1.0d ) {
> thumbnailHeight = (int) ( thumbnailDimension / imageRatio );
> }
> else {
> thumbnailWidth = (int) ( thumbnailDimension * imageRatio );
> }
>
> int longEdge = ( Math.max( imgHeight , imgWidth ) );
> int tempThumbnailEdge = (int) ( (float) thumbnailDimension *
> 1.25f );
> int subSample = (int) ( (float) longEdge / (float)
> tempThumbnailEdge );
>
> final ImageReadParam readParam =
> imgReader.getDefaultReadParam();
> if ( subSample > 1 ) {
> readParam.setSourceSubsampling( subSample , subSample , 0 ,
> 0 );
> }
>
> final BufferedImage tempThumbnailImage = imgReader.read( 0 ,
> readParam );
>
> final BufferedImage thumbnailImage = new BufferedImage(
> thumbnailWidth , thumbnailHeight ,
> BufferedImage.TYPE_INT_RGB );
> final Graphics2D graphics2D = thumbnailImage.createGraphics();
> graphics2D
> .setRenderingHint( RenderingHints.KEY_INTERPOLATION ,
> RenderingHints.VALUE_INTERPOLATION_BILINEAR );
> graphics2D.drawImage( tempThumbnailImage , 0 , 0 ,
> thumbnailWidth , thumbnailHeight , frame );
>
> final String thumbnailFileName = getThumbnailFileName(
> inputFile.getCanonicalPath() );
> final File thumbnailFile = new File( thumbnailFileName );
> final BufferedOutputStream thumbnailOut = new
> BufferedOutputStream(
> ( new FileOutputStream( thumbnailFile ) ) , 4092 );
> final JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(
> thumbnailOut );
> final JPEGEncodeParam encoderParam =
> encoder.getDefaultJPEGEncodeParam( thumbnailImage );
> encoderParam.setQuality( thumbnailQuality , false );
> encoder.setJPEGEncodeParam( encoderParam );
> encoder.encode( thumbnailImage );
> thumbnailOut.close();
>
> // Dispose of AWT components
> graphics2D.dispose();
> frame.dispose();
>
> response = thumbnailFile;
> }
> catch( Exception e ) {
> e.printStackTrace();
> }
> return response;
> }
>
> private static boolean isKnownFormat( String fileName ) {
> boolean response = false;
>
> if ( fileName == null || fileName.length() == 0 ) {
> return response;
> }
> int extensionPosition = fileName.lastIndexOf( '.' );
>
> if ( extensionPosition == -1 ) return response;
>
> final String extension = knownAliases( fileName.substring(
> extensionPosition ).toLowerCase() );
>
> for ( int x = 0 ; x < knownFormats.length ; x++ ) {
> if ( extension.equals( knownFormats[x] ) ) {
> return true;
> }
> }
>
> return response;
> }
>
> private static String knownAliases( String fileName ) {
> final String extension = fileName.substring( fileName.lastIndexOf(
> '.' ) ).toLowerCase();
> if ( extension.equals( ".jpg" ) ) return ".jpeg";
> if ( extension.equals( ".jpe" ) ) return ".jpeg";
> if ( extension.equals( ".tif" ) ) return ".tiff";
> return extension;
> }
>
> private static String getThumbnailFileName( String attachmentName ) {
> String result = null;
> int dotIndex = 0;
>
> // Get the position of the . before the extension
> dotIndex = attachmentName.lastIndexOf( "." );
> // Get the extension of the current file
> final String extension = attachmentName.substring( dotIndex + 1 );
> // Get the file name without the extension
> result = attachmentName.substring( 0 , dotIndex );
> // Build the thumbnail file name
> result = result + "_thumb_" + extension + ".jpg";
>
> return result;
> }
> }
>
> --
> View this message in context: http://www.nabble.com/using-JAI-to-create-a-thumbnail-as-a-JPEG-tf3701670.html#a11042093
> Sent from the JAI Projects - Interest mailing list archive at Nabble.com.
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: interest-unsubscribe@jai.dev.java.net
> For additional commands, e-mail: interest-help@jai.dev.java.net
>
>

----------------
Brian Burkhalter
Java Media, Imaging, and Graphics
Sun Microsystems, Inc.

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
This email message is for the sole use of the intended recipient(s)
and may contain confidential and privileged information. Any
unauthorized review, use, disclosure or distribution is prohibited.
If you are not the intended recipient, please contact the sender by
reply email and destroy all copies of the original message.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

---------------------------------------------------------------------
To unsubscribe, e-mail: interest-unsubscribe@jai.dev.java.net
For additional commands, e-mail: interest-help@jai.dev.java.net


snsf

Posts: 1
Re: using JAI to create a thumbnail as a JPEG
Posted: Jun 22, 2007 1:05 PM   in response to: mlevin
 
  Click to reply to this thread Reply

Folks,
I am new to using the java imaging APIs. I am trying to use java to create thumbnail images mainly for jpeg and gifs, and am not sure how to proceed. Ideally, the APIs shouldnt force me to materialize the full image in memory before scaling.

By reading this thread, it seems like there are 2 options:
(1) Use JAI APIs
(2) Use Java ImageIO APIs (by using the ImageReadParam)

Which of these is recommended?

Also, it was mentioned that the underlying decoder/reader used is what really matters and the decoder packaged with sun's java will read the entire image in memory. If thats true, can someone recommended other decoders (preferably free/open source, but commerical is also ok), that offer better performance (in terms of memory consumption).

Thanks much
Srinivas

Brian Burkhalter
Re: [JAI] Re: using JAI to create a thumbnail as a JPEG
Posted: Jun 22, 2007 2:36 PM   in response to: snsf
  Click to reply to this thread Reply

On Fri, 22 Jun 2007, jai-interest@javadesktop.org wrote:

> Folks,
> I am new to using the java imaging APIs. I am trying to use java to create thumbnail images mainly for jpeg and gifs,

For thumbnail generation I recommend the SubsampleAverage operation:

http://download.java.net/media/jai/javadoc/1.1.3/jai-apidocs/javax/media/jai/operator/SubsampleAverageDescriptor.html

Note that for a palette color image such as GIF this operation will not work
directly. For palette color imagery you need either to expand the image to
three-band RGB before applying the geometric operation or you need to use an
operation which does not interpolate the source image gray levels such as
nearest neighbor downsampling. Note that the negative side effect of the
latter approach is that you cannot apply low pass filtering at least by the
standard methods which implies that your thumbnail will suffer aliasing.

> and am not sure how to proceed. Ideally, the APIs shouldnt force me to
> materialize the full image in memory before scaling.

The APIs don't force this but for better or worse the JPEG and GIF
implementations can only load the entire image into memory. Formats which
support tiling such as TIFF and JPEG2000 do not have this drawback. Neither of
these formats really supports partial reading all that well anyway except
perhaps for JPEGs which include RSTn markers.

> By reading this thread, it seems like there are 2 options:
> (1) Use JAI APIs
> (2) Use Java ImageIO APIs (by using the ImageReadParam)
>
> Which of these is recommended?

The second. The JAI codecs pre-date the Java Image I/O Framework APIs and were
provided as a user convenience.

> Also, it was mentioned that the underlying decoder/reader used is what really matters and the decoder packaged with sun's java will read the entire image in memory. If thats true, can someone recommended other decoders (preferably free/open source, but commerical is also ok), that offer better performance (in terms of memory consumption).

If you find one please let us know where it is.

Thanks,

Brian

----------------
Brian Burkhalter
Java Media, Imaging, and Graphics
Sun Microsystems, Inc.

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
This email message is for the sole use of the intended recipient(s)
and may contain confidential and privileged information. Any
unauthorized review, use, disclosure or distribution is prohibited.
If you are not the intended recipient, please contact the sender by
reply email and destroy all copies of the original message.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

---------------------------------------------------------------------
To unsubscribe, e-mail: interest-unsubscribe@jai.dev.java.net
For additional commands, e-mail: interest-help@jai.dev.java.net


b06

Posts: 1
Re: [JAI] Re: using JAI to create a thumbnail as a JPEG
Posted: Oct 19, 2007 10:56 AM   in response to: Brian Burkhalter
 
  Click to reply to this thread Reply

http://weblogs.java.net/blog/robogeek/archive/2007/05/the_image_resiz.html

Will this work better? I think it stills load to memory but I find the performance acceptable (ie. didn't notice may performance hit).




 XML java.net RSS