1

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.

tuanva
  • 13
  • 6
  • 6
    "It doesn't work as expected" - What does it do then, and how is it different from what you expect? Don't just say "it doesn't work" - explain it, otherwise you're just making it hard for people to help you. – Jesper Nov 29 '12 at 13:46
  • Sorry about that, I've already edited. The problem is the canvas is empty and doesn't show the image. – tuanva Nov 29 '12 at 13:53
  • 1
    For reference, there's a complete example [here](http://stackoverflow.com/a/5864503/230513). – trashgod Nov 29 '12 at 14:23
  • Have you tried RGB instead of ARGB? – eSuarez Nov 29 '12 at 14:48
  • This may be a silly question, but is your file (referenced by `MAP_FILENAME`) in the same location on your windows machine (as on your mac)? I personally wasn't able to recreate the problem with the code provided, but I may be missing a configuration... – Nick Rippe Nov 29 '12 at 14:53
  • `sourceImage = ImageIO.read(new File(MAP_FILENAME));` The map will likely become an [tag:embedded-resource] by the time this is deployed, so the map will only be accessible by `URL` (not `File`). – Andrew Thompson Nov 29 '12 at 22:14
  • Thanks for all your answers, my MAP_FILENAME actually is a physical file on my computer and in the same directory (root directory).That's why it works fine on my Mac. @eSuarez: I had tried that and the whole image became absolutely dark, i mean black. Anyway, I fixed it now. Thanks you guys! – tuanva Dec 05 '12 at 22:22

2 Answers2

0

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.

MadProgrammer
  • 343,457
  • 22
  • 230
  • 366
0

Thank you for pointing out my mistakes. There is some missing code in my question (the Graphics2D g2d - it's just an unassigned variable) so it doesn't compile. Sorry about that.

This is how I fixed it:

           `sourceImage = ImageIO.read(new File(MAP_FILENAME));

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

            float[] scales = { .5f, .5f, .5f, 1f };
            float[] offsets = new float[4];
            op = new RescaleOp(scales, offsets, null);

            Graphics2D g1 = bi.createGraphics();

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

            op.filter(sourceImage, bi);`

I just use the same value for RGB in the scales array (that's how it supposed to be) then draw the filtered image.

            `g2d.drawImage(bi, 0, 0, 500, 382, null);`

Cheers

tuanva
  • 13
  • 6