You will most likely have seen the graphics files for Minecraft by our own Markus Persson. If not then you should take a look at a texture pack for Minecraft. I really want to know how to load the individual images from those squares, I know how to load a single image but not how to take certain pixels from that image.
Using java.awt.image.BufferedImage, you could use the Graphics’s 10-param drawImage method:
drawImage(Image i, int destinationX, int destinationY, int destinationX2, int destinationY2, int sourceX, int sourceY, int sourceX2, int sourceY2, ImageObserver io);
Example:
BufferedImage original = //get entire image
//create new image using a square's width and height
BufferedImage square = new BufferedImage(width,height);
Graphics g = square.getGraphics();
//draw that square into the new image
g.drawImage(original, 0, 0, width, height, x, y, x+width, y+height, null);
g.dispose();
Or you could use getSubimage() to chop it up into little images. I just dislike the 10-param drawImage(), seems exsessive when you could just chop the image up and draw each one by itself with the nice 4-param drawImage(Image img, int x, int y, ImageObserver observer) method.
Worth noting that Images returned from getSubimage share the parent Image’s DataBuffer.
So if you had a mostly blank sprite sheet, created subimages for all the sprite frames, and then disposed of the parent image expecting the memory it used to be recovered by the GC, you’d be mistaken.
Huh I’ve never had problems with this, but since the data can still be accessed through the subimage wouldn’t the GC leave it alone? If it’s a problem you could do something like this to make sure it’s ok.
public static BufferedImage[][] parseImage(BufferedImage src, int subWidth, int subHeight)
{
BufferedImage[][] imgs = new BufferedImage[src.getWidth() / subWidth][src.getHeight() / subHeight];
GraphicsConfiguration gc = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDefaultConfiguration();
for(int x = 0; x < src.getWidth() / subWidth; x++)
{
for(int y = 0; y < src.getHeight() / subHeight; y++)
{
BufferedImage subImage = gc.createCompatibleImage(subWidth, subHeight, src.getTransparency());
BufferedImage subSrc = src.getSubimage(x * subWidth, y * subHeight, subWidth, subHeight);
subImage.createGraphics().drawImage(subSrc, 0, 0, null);
imgs[x][y] = subImage;
}
}
return imgs;
}
EDIT: To simplify my example and expand upon ra4kings:
BufferedImage square = new BufferedImage(width, height, original.getType());
BufferedImage subImage = original.getSubimage(x, y, width, height);
Graphics2D g = square.createGraphics();
g.drawImage(subImage, 0, 0, null);
Yeah, it’s a nasty gotcha. The worst side-effect IMHO is that because it’s just a reference into a much bigger slice of data the drawing speed may be much worse than if you create a new image of the right size and draw the portion into it.
Yep either that or just use the 10-param method for splitting.
However, I remember a while back there was a thread that showed how drawImage somehow alters the image a bit. Someone showed that drawImage doesn’t draw the image bit by bit but does some changes.