Need help splitting PNG images

Hey, here is my problem:
Right now I have some methods that read in a PNG image into a BufferedImage. I then take the BufferedImage and convert it into a usable OpenGL texture. My question is this: is there any way to split the BufferedImage into multiple smaller BufferedImages?

I’ve tried using the BufferedImage.getSubimage(), however it just returns a reference to the original data, so a new smaller image is not created.

Is there a way to take a BufferedImage and make a new, smaller derivative of it (that is not a reference but a completely new BufferedImage object)?

One problem I seem to be having is that my BufferedImage is of TYPE_CUSTOM whenever I load in the PNG using BufferedImage img = ImageIO.read(url); This makes me unable to create another BufferedImage with the same byte scheme. Any Ideas?

Hi
I’m at work right now, so i cant check exactly how to do this, but I did it by doing a new bufferedImage, like:
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); and then
Graphics g = image.getGraphics()

then you use your original image and use one of the drawImage methods to draw the specified part of your original image onto the new image, eg:
g.drawImage(originalImage, 0,0, width, height, 0,0, 100,100,null, null); to draw the subimage 0,0 to 100,100 onto the new image and scale it to its size.

Sorry for the vague code, but I cant check it right now :frowning:

// Gregof

I am learning the example of lwjgl 0.92, the spaceinvaders.I try to combine 3 alien sprite images into one png file.It’s very useful, isn’t it?
the code is listed below.
my problem is:the first frame is correct, and the second is wrong, it’s actually a mixture of the first and the second sprite. the third is wrong either. it’s a mixture of all sprite.
if I add a statement like g.clearRect(…)(see the code below), it works, the animate can play correctly, but transparent lost.
does anybody can tell me why, and how to solve this problem. thanks.


    public Texture getFrameTexture(String resourceName, int width, int height,
                                   int frame) throws IOException {
        Texture tex = (Texture) table.get(resourceName+frame);

        if (tex != null) {
            return tex;
        }

        BufferedImage bufferedImage = loadImage(resourceName);
        int totalFrame = bufferedImage.getWidth()/width;

        if(frame >= totalFrame){
            frame = 0;
            tex = (Texture) table.get(resourceName+frame);
            if (tex != null) {
                return tex;
            }
        }

        WritableRaster raster;
        BufferedImage[] frames = new BufferedImage[totalFrame];

        if (bufferedImage.getColorModel().hasAlpha()) {
            raster = Raster.createInterleavedRaster(DataBuffer.TYPE_BYTE,width, height,4,null);
            for(int i= 0; i < totalFrame; i ++){
                frames[i] = new BufferedImage(glAlphaColorModel,raster,false,new Hashtable());
            }
        } else {
            raster = Raster.createInterleavedRaster(DataBuffer.TYPE_BYTE,width, height,3,null);
            for(int i= 0; i < totalFrame; i ++){
                frames[i] = new BufferedImage(glColorModel,raster,false,new Hashtable());
            }
        }

        //??????????????????????????????????????????????????????
        // problem is here?????????????????????????????????????????
        Graphics g=null;
        for(int i = 0; i < totalFrame; i ++){
            g = frames[i].getGraphics();
            //g.clearRect(0,0,width, height); //it works, but transparent lost.
            g.drawImage(bufferedImage, -i*width, 0, null);

            tex = getTexture(frames[i],
                    GL11.GL_TEXTURE_2D, // target
                    GL11.GL_RGBA,     // dst pixel format
                    GL11.GL_LINEAR, // min filter (unused)
                    GL11.GL_LINEAR);

            table.put(resourceName+i,tex);
        }
        //end problem????????????????????????????????????????????

        return (Texture) table.get(resourceName+frame);
    }

I found the reason!!! I didn’t create raster for each frame, but use one raster object for all frames. now it works, the right code is pasted below.


        if (bufferedImage.getColorModel().hasAlpha()) {
            for(int i= 0; i < totalFrame; i ++){
                raster = Raster.createInterleavedRaster(DataBuffer.TYPE_BYTE,width, height,4,null);
                frames[i] = new BufferedImage(glAlphaColorModel,raster,false,new Hashtable());
            }
        } else {
            for(int i= 0; i < totalFrame; i ++){
                raster = Raster.createInterleavedRaster(DataBuffer.TYPE_BYTE,width, height,3,null);
                frames[i] = new BufferedImage(glColorModel,raster,false,new Hashtable());
            }
        }

See nehe’s tutorial Lesson 17:2D texture font, I found it’s more effective to use Display Lists than to split png image into frames, is it right?!

Texture changes come at a cost, and using a lot of small textures might waste texture memory due to alignment etc.

Using a bigger texture and indexing it by changing the UV coords are by far the fastest method.