Creating BufferedImage

L

Larry Coon

I'm confused about how to create a BufferedImage.
I'm trying to use a JFileChooser to select a file,
and load the selected (image) file into a
BufferedImage. I'm using this approach:

JFileChooser fileChooser = new JFileChooser();
fileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY);

int result = fileChooser.showOpenDialog(MyClass.this);
if (result == JFileChooser.CANCEL_OPTION) return;

File file = fileChooser.getSelectedFile();
if (file == null || file.equals("")) return;

BufferedImage image = (BufferedImage)
Toolkit.getDefaultToolkit().createImage(file.getPath());


The downcast doesn't work -- I get a ClassCastException.
But I don't see another way to get a BufferedImage from
an Image. Am I missing something obvious?
 
M

Marco Schmidt

Larry Coon:

[...]
BufferedImage image = (BufferedImage)
Toolkit.getDefaultToolkit().createImage(file.getPath());


The downcast doesn't work -- I get a ClassCastException.
But I don't see another way to get a BufferedImage from
an Image. Am I missing something obvious?

Toolkit doesn't return a BufferedImage object. It doesn't have to,
because createImage "only" returns an Image.

Do you really need a BufferedImage? For simple usage (display it
somewhere) a normal Image is sufficient.

If you _do_ need a BufferedImage, try ImageIO.read if you can rely on
Java 1.4 being available.

Otherwise, after loading with Toolkit you will have to create a new
BufferedImage of the correct resolution, call getGraphics on that
BufferedImage and use the drawImage method of that Graphics object to
draw the Image object Toolkit has loaded into the BufferedImage.

Regards,
Marco
 
X

Xela

Can you indicate how to set the correct size to the created buffered image?
Image itself is not "size" aware, is it?


Marco Schmidt said:
Larry Coon:

[...]
BufferedImage image = (BufferedImage)
Toolkit.getDefaultToolkit().createImage(file.getPath());


The downcast doesn't work -- I get a ClassCastException.
But I don't see another way to get a BufferedImage from
an Image. Am I missing something obvious?

Toolkit doesn't return a BufferedImage object. It doesn't have to,
because createImage "only" returns an Image.

Do you really need a BufferedImage? For simple usage (display it
somewhere) a normal Image is sufficient.

If you _do_ need a BufferedImage, try ImageIO.read if you can rely on
Java 1.4 being available.

Otherwise, after loading with Toolkit you will have to create a new
BufferedImage of the correct resolution, call getGraphics on that
BufferedImage and use the drawImage method of that Graphics object to
draw the Image object Toolkit has loaded into the BufferedImage.

Regards,
Marco
 
L

Larry Coon

Marco said:
Toolkit doesn't return a BufferedImage object. It doesn't have to,
because createImage "only" returns an Image.

Do you really need a BufferedImage? For simple usage (display it
somewhere) a normal Image is sufficient.

Yes, I want to fiddle with the bits, and BufferedImage
supports getRGB & setRGB.
If you _do_ need a BufferedImage, try ImageIO.read if you can rely on
Java 1.4 being available.

I can. It's for me. I'll check this out.
Otherwise, after loading with Toolkit you will have to create a new
BufferedImage of the correct resolution, call getGraphics on that
BufferedImage and use the drawImage method of that Graphics object to
draw the Image object Toolkit has loaded into the BufferedImage.

Not sure I follow this. Are you saying to do something
like...

// Assuming Image image is loaded defined & initialized.
BufferedImage bi = new BufferedImage(image.getWidth(null),
image.getHeight(null), BufferedImage.TYPE_SOME_TYPE);
Graphics g = bi.getGraphics();
g.drawImage(image, 0, 0, bi); // Here's where I'm lost
 
L

Larry Coon

Marco said:
If you _do_ need a BufferedImage, try ImageIO.read if you can rely on
Java 1.4 being available.

Follow-up to my previous response: ImageIO.read worked
perfectly. Thanks!
 
B

Babu Kalakrishnan

Larry said:
Not sure I follow this. Are you saying to do something
like...

// Assuming Image image is loaded defined & initialized.
BufferedImage bi = new BufferedImage(image.getWidth(null),
image.getHeight(null), BufferedImage.TYPE_SOME_TYPE);
Graphics g = bi.getGraphics();
g.drawImage(image, 0, 0, bi); // Here's where I'm lost

Yes that's exactly what Marco was suggesting. Essentially you're
transferring the contents of the source Image into a BufferedImage
object by painting it onto a graphics context derived from the
BufferedImage.

However there is a gotcha you should be aware of when using the code
above. Java performs imageloading in a background thread and therefore
the getWidth / getHeight methods will not return the actual values till
the actual loading has been completed. So you should somehow ensure that
the loading is complete (or at least that the Width/height parameters
have been loaded). You can do this in several ways - using a
MediaTracker, using ImageIcons or implementing an ImageObserver interface.

Of course if you don't need to be compatible with pre-1.4 JREs, the
ImageIO classes would be a better alternative.

BK
 
L

Larry Coon

Babu said:
Yes that's exactly what Marco was suggesting. Essentially you're
transferring the contents of the source Image into a BufferedImage
object by painting it onto a graphics context derived from the
BufferedImage.

However there is a gotcha you should be aware of when using the code
above. Java performs imageloading in a background thread and therefore
the getWidth / getHeight methods will not return the actual values till
the actual loading has been completed. So you should somehow ensure that
the loading is complete (or at least that the Width/height parameters
have been loaded). You can do this in several ways - using a
MediaTracker, using ImageIcons or implementing an ImageObserver interface.

Of course if you don't need to be compatible with pre-1.4 JREs, the
ImageIO classes would be a better alternative.

Thanks for the comments. I tried implementing it via the
Graphics context, and I ran right into your gotcha -- the
getWidth & getHeight were returning -1. ImageIO did exactly
what I wanted with a single call, so that's what I stayed
with.

Now I'm trying to work through another problem, which I assume
is with the way Swing optimizes repaint calls. I want to play
with different image processing algorithms (blur, sharpen,
various erases, etc), so I'm writing an interface for the
various image processors, eg:

public interface ImageProcessor {
public void processImage(BufferedImage image);
}

Then I want to select an ImageProcessor with a JComboBox and
invoke the current selection with a JButton.

I want some of the image processors (such as blur) to do their
job and repaint() when they are done. I want others (such as
random erase) to update the display continually as they process
the image. So I thought a random erase might look like this:

public class RandomErase implements ImageProcessor {
public void processImage(BufferedImage image) {
Random r = new Random();
int iterations = image.getWidth() * image.getHeight() / 1000;

for (int i = 0; i < iterations; i++) {
for (int j = 0; j < 1000; j++) {
image.setRGB(
Math.abs(r.nextInt()) % image.getWidth(),
Math.abs(r.nextInt()) % image.getHeight(),
0
);
}
repaint(); // Repaint every thousand pixels.
}
}
}

Problem is, repaint() doesn't actually run until after the
entire function finishes. I read here:

<http://java.sun.com/docs/books/tutorial/uiswing/overview/draw.html>

which says that while an event is being handled, no painting will
occur (I'm calling processImage from a button handler). So I put
the call to processImage into a Runnable and used invokeLater, but
it still only does a repaint after it's all done. I can't find a
way to do a continuous update of the image as I'm processing it.
 
L

Larry Coon

Larry Coon wrote:

(mostly snipped)
I can't find a
way to do a continuous update of the image as I'm processing it.

Follow-up to my previous post: problem solved. I had the
ImageProcessor implement Runnable, put the logic in the
run method, and had the button handler create & start a
thread to run it.
 

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,731
Messages
2,569,432
Members
44,832
Latest member
GlennSmall

Latest Threads

Top