WritableRaster problems

I don’t know why but when I try to paint the manipulated image nothing has changed.

private void render(Graphics2D g2d){
        
        WritableRaster wr = lithosphere.getRaster();
        
        int lookup;
        
        double mapHeight;
        
        double[] k = {0,0,0}, data;
            
        for (int x = 0; x < WIDTH; x++) {

            for (int y = 0; y < HEIGHT; y++) {

                mapHeight = (map[x][y].getHeight() <= 650) ? 650 : map[x][y].getHeight();

                lookup = (int)(mapHeight / 650) - 1;

                data = heightmap_raster.getPixel(lookup, 0, k);

                wr.setPixel(x, y, data);

            }

        }
        
        g2d.drawImage(lithosphere, 0, 0, null);
        
    }

The raster is changing but when I go to draw the image nothing is drawn. The image stays the same. Any ideas?

Oh and I didn’t know where this was supposed to go. And please do not give me a link to something. I’ve been on this for a while and still can’t figure it out.

Is there another drawImage(lithosphere, 0, 0, null); command somewhere in your code?

If so, maybethat other drawImage is the only one actually displaying. This could occur for a number of reasons, for example, if the EDT is “collapsing” draw commands, or if the Graphics2D parameter you are passing is somehow not connected to the displaying component (JPanel? JComponent? Canvas?) or that component is not getting a repaint() or equivalent.

One idea for testing, simply make a very different graphic and make your code thus:

private void render(Graphics2D g2d){
        
        lithosphere = testImage; // testImage is an image that is obviously different
        
        g2d.drawImage(lithosphere, 0, 0, null);
        
    }

If the testImage displays, then you KNOW it is a problem with the WritableRaster code. But I’m starting with the assumption it is not, since you said you inspected the graphic and confirmed that it IS changing.

I don’t see any obvious problems with the code. Can you produce a minimal self-contained (i.e. compilable and runnable with just the standard API for dependencies) program which demonstrates the same problem?

No, that is the only place in which the image is being rendered. Also the image is being drawn onto a JPanel. The Graphics2D device is passed by the JPanel’s paintComponent(Graphics g) method. Which is shown below.

The funny thing about it is if I fill a rectangle onto the image in the start before any changes are made, say a red box, it renders that just fine. But no changes are being made to the raster.

private class gtPanel extends JPanel {
        
        public void paintComponent(Graphics g) {
        
            Graphics2D g2d = (Graphics2D) g;

            super.paintComponent(g);

            render(g2d);

            g2d.dispose();

        }
        
}

I have also tried this with no success either… The array K was deleted and data was used as the input array for the pixel. The array data shows a change when this is called,

heightmap_raster.getPixel(lookup, 0, data);

However nothing still works. I don’t understand why nothing is showing a change when the image is rendered.

private void render(Graphics2D g2d){
        
        WritableRaster wr = lithosphere.getRaster().createCompatibleWritableRaster();
        
        int lookup;
        
        double mapHeight;
        
        double[] data = {0,0,0};
            
        for (int x = 0; x < WIDTH; x++) {

            for (int y = 0; y < HEIGHT; y++) {

                mapHeight = (map[x][y].getHeight() <= 650) ? 650 : map[x][y].getHeight();

                lookup = (int)(mapHeight / 650) - 1;

                heightmap_raster.getPixel(lookup, 0, data);

                wr.setPixel(x, y, data);

            }

        }
        
        g2d.drawImage(lithosphere, 0, 0, null);
        
}

A couple of the issues that I mentioned could still be causing the problem, even if there is just the one imageDraw.

Here’s another idea: put in a System.out.println() message every time render gets called, just to make sure it is getting called multiple times.

Also, can you show us the calling code and where you repaint() the JPanel? Changing the graphic does nothing unless you redisplay the JPanel. It may not be called, or it may be a call that is getting collapsed by the EDT.

I figured out the problem.

The bug was serveral things. The for-loops WIDTH and HEIGHT conditions were not set correctly and were giving false states. As for the WritableRaster, the code below is what now works. Strange, you have to set the data in the buffered image you are currently working on. Apparently the reference is a copy so I was not working directly on the image.

private void render(Graphics2D g2d){
        
        WritableRaster wr = lithosphere.getRaster(); // <-------------- Not making a copy, just getting the reference
        
        Color colorRef;
        int lookup, color;
        
        double mapHeight;
        
        int[] data = {0,0,0}; //<----------- This was changed to int
            
        Graphics2D lg2d = lithosphere.createGraphics();
        
        for (int x = 0; x < JGeoTec.WIDTH; x++) { // <------------------ Bug here

            for (int y = 0; y < JGeoTec.HEIGHT; y++) { // <------------------ Bug here

                mapHeight = (map[x][y].getHeight() <= 650) ? 650 : map[x][y].getHeight();

                lookup = (int)(mapHeight / 650) - 1;

                heightmap_lookup_raster.getPixel(lookup, 0, data);
                
                wr.setPixel(x, y, data);

            }

        }
        
        renderFaults(wr);
        
        //lithosphere.setData(wr); //<-------- ONLY needed if you are creating a copy of a raster
        
        g2d.drawImage(lithosphere, null, null);
        
}

I am able to work on 1024x1024 pixels very quickly. Very useful stuff here if you are wanting to work on images right down to the pixels. setRGB methods are very slow…

****** EDIT *******

I was creating a new raster by calling createCompatiableWritableRaster or something. OTHERWISE the code above is completely correct.