Image Cropping

Hi all, my first post here!

I’m trying to put all my character animations in one GIF file, read it in then chop it up and put each piece into an array. I got it working fine in a JApplet, using CropImageFilter ect, but I want it to happen in a JFrame.

The problem is you can’t use getDocumentBase() in a JFrame, so reading in is a bit different. My question is, do I have to use ImageIcon, and if so, how do I chop an ImageIcon up?

Please be patient, I’m still new to graphics in Java. :slight_smile:

Use ImageIO to read the image (javax.imageio.ImageIO). Loading it via the ClassLoader using getResource() or getResourceAsStream() might be worth while. If you use this then you’ll get a BufferedImage on which you can call getSubImage() which will grab a section of the image.

Kev

Do you really want to do split the image up? We use multiple animation frames in our games but leave them all on a single image. I presume you want do draw a specific frame of animation, if so this is what you need:

drawImage(Image img, int dx1, int dy1, int dx2, int dy2, int sx1, int sy1, int sx2, int sy2, ImageObserver observer)

This will draw a subsection of the image. To get a specific frame from the image either store the offsets into your array and read from them when you come to draw:


void drawFrame(Graphics g,Image i, int x, int y, int frame)
{
    g.drawImage(i, x, y, x+WIDTH, y+HEIGHT, frameOffsetX[frame], frameOffsetY[frame], frameOffsetX[frame]+WIDTH, frameOffsetY[frame]+HEIGHT, null);
}

WIDTH & HEIGHT are the sizes of the frames themselves.

If the frames are all the same size and arranged:
1 2 3 4
5 6 7 8
9 10 11 12
13 14 15 16
etc.

just convert the index into the offsets like so:


int sx1 = (frame&3)*WIDTH; // Same as (frame % 4) - modulus
int sy1 = (frame>>2)*HEIGHT; // Same as (frame / 4) - divide

This saves using the arrays for the offsets into the image.

Its good to get into the habit of doing this, as when it comes to accelerating images with hardware you get better perfromance by using a few large images than many small ones.

I hope this helps, otherwise it should give you something to think about :wink:
Good luck with your game programming,

  • Dom

This works pretty well. Thanks a lot, just one quick question, is this the best way to read in an Image in a JFrame:


tempImage = getToolkit().getImage("Hero.gif");

Or is there a faster way?

Faster I can’t judge but I find the following more natural:[quote]import javax.imageio.ImageIO
BuifferedImage bimg = ImageIO.read(new File(“Pic.png”));
[/quote]
… because there’s also an equivalent ImageIO.write() method.

With[quote]String[] list = ImageIO.getReaderFormatNames();
[/quote]
and[quote]
list = ImageIO.getWriterFormatNames();
[/quote]
… you’ll get the implemented readers and writers. For Java 1.4.2 this currently is:[quote]
Read: [Png, Jpg, Gif]
Write: [Png, Jpg]
[/quote]
In a related thread Cas mentioned some code how to change the compression ration for Jpegs… http://www.java-gaming.org/cgi-bin/JGNetForums/YaBB.cgi?board=2D;action=display;num=1087844685;start=5#5

Wow, you guys have been really helpful. I’ve got my own little guy moving around now!

So here’s another question: can anyone point me to a good tutorial on making a scrolling tile-based map, if any exist? I’ve found a couple of games with source code but it all goes over my head.

A tutorial… mh… well the GAGE library has supports that kind of stuff.

However, it isn’t that difficult :slight_smile:

-each tile has a number
-the map is a 2d array with ints

let’s say you use 640x480 and 32x32 tiles

640/32=20
480/32=15

So you have at least 20*15 tiles on screen.

If it scrolls horizontally it’s 21*15.

If it scrolls vertically it’s 20*16.

If it scrolls in both directions it’s 21*16.

Why? Well, because you have tiles wich are partial visible at the edges :wink:

So grab pen&paper and draw some sketches (thinking is fun ;D). I’m sure you are able to figure it out. Btw you can just ignore these cases were you have a row/column less :slight_smile:

This is only true for systems with more video memory than your going to use. If you’re going to be going over the memory size (targeting at low end machine maybe) then smaller images make more sense since this gives you a high granularity to swap in and out images. The graphics card is more likely to find an optimum set of images that don’t require swapping during rendering of the paritcular level/area.

Kev