This page describes most of the things that you can do loading images into Java. It also assumes that you are using Eclipse. Eclipse has some strange behaviour when it comes to locating resource files (such as images). We'll deal with that later.
Our goals in this lesson are to
Images can be loaded with an ImageObserver. This is some object that does something when the whole image is loaded -- useful for images thate take a long time to load, for example large images or an image that is being downloaded from the internet. We don't use this often so just put "null" for the image observer when asked.
There is a MediaTracker class that allows you to wait until all images are loaded. It's probably more useful than imageobserver, but you'll have to read up on these yourself.
ImageIcons are used for situations where you want to put an icon (a small image) onto something like a JButton or a JLabel.
They display the whole image and do not allow resizing to fit the destination. Thus you have to find an image (icon) that is the exact size that you want displayed.
Sample code
ImageIcon icon = new ImageIcon("images/myimage.jpg");
JButton btn = new JButton(icon);
Note that we are just specifying the filename where the image is.
Also, always use / for path separators, not \. ie. ""c:/cat.gif" not "c:\cat.gif" (you have to escape the \ for it to work: "c:\\cat.gif")
The ImageIcon constructor can get the image from a string (filename), a URL, as well as an Image.
We'll look at where to actually put the images file later on
Scaling an ImageIcon
What if you want to scale a large image down so that it fits onto a JButton?
Sample code
Here we load an image onto the a card (actually a JButton). To do this we have to make an image and then change it to an imageicon
int cardW = 200; int cardH = 160; Image img = null; //load the image try { img = ImageIO.read(new File("kittens.jpg")); } catch (IOException e) { System.out.println(e.toString()); System.exit(0); } //scale the image Image scaledImage = img.getScaledInstance(cardW, cardH, Image.SCALE_DEFAULT); //convert to an ImageIcon ImageIcon icon = new ImageIcon(scaledImage); JButton card1 = new JButton(icon); //the JButton is now 200x160
NOTE: (1) we loaded the image in a new way 2. We created the ImageIcon using an image in the contrstuctor
The image class. Image is an abstract class, so you can never use "new Image()". Instead use new BufferedImage().
However you can use Image img = ...something else that makes an image...
Sample code
Get an image icon and change it to an image
ImageIcon icon = new ImageIcon("myimage.jpg");
Image img = icon.getImage();
For more on using Image, see BufferedImage below
There's not a whole lot of difference between the two except that bufferedimages will not flicker in animated programs.
"BufferedImage, in fact, is a subclass of Image. BufferedImage gives you all sorts of control over the actual data that makes up the image and provides many capabilities beyond the basic Image class. Because it's a subclass of Image, you can still pass a BufferedImage to any of Graphics2D's methods that accept an Image. Why aren't all Images BufferedImages? Because BufferedImages are memory intensive."
-- from https://www.safaribooksonline.com/library/view/learning-java-4th/9781449372477/ch21s01.html
I don't know that BufferedImages really use significantly more resources than Images. They do allow you to manipulate the individual pixels of an image (which you can't do with the Image class).
The Graphics.drawImage() method has a lot of different possible parameters. It's good to look over them all.
All of them have "ImageObserver" as the last parameter. We'll just put null
here.
//drawing onto graphics in paintComponent(Graphics g)
- g.drawImage(image, 0, 0, null); //This just places the image at (0,0) on the screen. It offers no control over how large the image is.
- g.drawImage(image, 0, 0, getWidth(), getHeight(), null); //This stretches the image to fill the screen
- g.drawImage(playerImg, player.x, player.y, player.width, player.height, null); //draw the player image into the player rectangle (image is scaled to fit)
- g.drawImage(image, 0, 0, 100, 100, null); //scales the image to fill a 100x100 square located at (0,0).
- g.drawImage(image, dx, dy, dw, dh, sx, sy, sw, sh, null);
This last form lets you specify the destination rectangle, as all of the previous examples do, but also lets you specify the source rectangle, which means that you can just select one part of an image to draw. This is especially useful for spritesheets.
In all of these examples you should always check to see if the image is null before drawing it or you'll get an error:
if (image != null) g.drawImage(image, 0, 0, 100, 100, null);
asteroid = new Rectangle (200,200, 64, 64); // starting location and 64x64 pixels size of asteroid image g.drawImage(imgAsteroid, //the image file asteroid.x, asteroid.y, asteroid.x + asteroid.width, asteroid.y + asteroid.height, //destination 0,0, asteroid.width, asteroid.height, //source null); //imageObserver
This is mostly used for loading (and saving) images.
There are a whole bunch of ways to load an image:
"It is easy to load an image with the static read() methods of the ImageIO class, which accept either a File, URL, or InputStream. Images loaded by the ImageIO.read() methods are fully loaded before they are returned, so the method blocks until they are done." -- from Safari Books
Saving an image
This will probably be a BufferedImage because you can modify them.
File outFile = new File("/tmp/myImage.png");
ImageIO.write( buffimg , "png", outFile ); //The second argument is a string identifier that names the image type.
Method to load images
/* This method loads an image from a filename (which includes the relative path).
* It returns the BufferedImage or a null if the image doesn't load. */
static BufferedImage loadImage(String fileName) {
BufferedImage img = null;
try {
img = ImageIO.read(new File(fileName));
} catch (IOException e) {
e.printStackTrace();
JOptionPane.showMessageDialog(null, "An image failed to load: " + fileName , "ERROR", JOptionPane.ERROR_MESSAGE);
}
return img;
}
I'll be posting complete working programs Monday evening, illustrating all of the things mentioned above along with a video showing how to make an executable Jar with resources.