Search code examples
javaimageswinggraphics2dpaint

Darkening image using Graphics2D issue in Windows 7 64-bit


My small Java program is trying to darken a png image. It's working fine on my Mac but when I try to run it on a Windows PC with java 1.7_07 installed but it doesn't show anything at all except an empty JPanel, the image is completely disappeared.

Here is the code:

class MapCanvas extends JPanel {
    private Color color;
    RescaleOp op;
    BufferedImage sourceImage, bi;

    public MapCanvas() {
        try {
            sourceImage = ImageIO.read(new File(MAP_FILENAME));

            bi = new BufferedImage(sourceImage.getWidth(), sourceImage.getHeight(), BufferedImage.TYPE_INT_ARGB);

            op = new RescaleOp(.8f, 0, null);
            bi = op.filter(bi, null);

            Graphics2D g = bi.createGraphics();

            g.drawImage(sourceImage, 0, 0, 500, 382, null);
            g.dispose();

        } catch (Exception e) {
            e.printStackTrace();
        }

        // set size for the panel
        Dimension size = new Dimension(500, 382);
        this.setBackground(new Color(34, 102, 187));
        setPreferredSize(size);
        setSize(size);
        setLayout(null);
    }

    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        g2d = (Graphics2D) g;

        g2d.drawImage(bi, op, 0, 0);  
    }
}

Anyone know why I'm getting this? Many thanks.


Solution

  • I don't seem to have any issues, BUT, several things jump out at me about this example...

    Firstly, I don't see why you've done this...

    try {
        sourceImage = ImageIO.read(new File("C:/Users/shane/Dropbox/issue453.jpg"));
    
        bi = new BufferedImage(sourceImage.getWidth(), sourceImage.getHeight(), BufferedImage.TYPE_INT_ARGB);
    
        op = new RescaleOp(.1f, 0, null);
        bi = op.filter(bi, null);
    
        Graphics2D g = bi.createGraphics();
    
        g.drawImage(sourceImage, 0, 0, 500, 382, null);
        g.dispose();
    
    } catch (Exception e) {
        e.printStackTrace();
    }
    

    Then done this...

    public void paintComponent(Graphics g) {
        super.paintComponent(g);
    
        g2d = (Graphics2D) g;
        g2d.drawImage(bi, op, 0, 0);
    }
    

    You're basically double apply the RescaleOp.

    It could simply just apply the RescaleOp directly to the sourceImage...

    public void paintComponent(Graphics g) {
        super.paintComponent(g);
    
        g2d = (Graphics2D) g;
        g2d.drawImage(sourceImage, op, 0, 0);
    }
    

    Unless you're concerned about performance, in which case you should simple draw the bi without any BufferedImageOp

    g2d.drawImage(bi, 0, 0, this);
    

    Secondly, your example won't compile because you've not defined g2d in your paintComponent method. This is either an oversight (which is fine) OR you are caching the Graphics object, which is not fine.

    Graphics objects are stateless, they do not persist between repaints, you should NEVER cache them or rely on getGraphics.