3

I'm currently designing Pac Man in java using swing. I have PNG images that are drawn on screen using the following statement.

wall = new ImageIcon(GamePanel.class.getResource("wall.png")).getImage();
g2d.drawImage(wall, x, y, this);

The problem I'm having is that it seems to render a very low colour depth rendition of the actual file. It seems like it does retain transparency (grey background is the Panel bg color), but it loses color depth.

The actual image looks like this: enter image description here When running, it looks like this: enter image description here

Does anyone have a solution? Thanks!

Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
user1305850
  • 141
  • 1
  • 2
  • 13

4 Answers4

4

Something seems definitely wrong in the 2nd image. See it here on a black BG and it looks very different - without the 'halo'.

Test Yellow Dot Image

import java.awt.*;
import java.net.URL;
import javax.swing.*;

public class TestYellowDotImage {

    public static JLabel getColoredLabel(Icon icon, Color color) {
        JLabel label = new JLabel(icon);
        label.setBackground(color);
        label.setOpaque(true);

        return label;
    }

    public static void main(String[] args) throws Exception {
        URL url = new URL("https://i.stack.imgur.com/1EZVZ.png");
        final Icon icon = new ImageIcon(url);
        Runnable r = new Runnable() {

            @Override
            public void run() {
                JPanel gui = new JPanel(new GridLayout(0, 4));

                gui.add(new JLabel(icon));
                gui.add(getColoredLabel(icon, Color.BLACK));
                gui.add(getColoredLabel(icon, Color.WHITE));
                gui.add(getColoredLabel(icon, Color.RED));

                JOptionPane.showMessageDialog(null, gui);
            }
        };
        // Swing GUIs should be created and updated on the EDT
        // http://docs.oracle.com/javase/tutorial/uiswing/concurrency/initial.html
        SwingUtilities.invokeLater(r);
    }
}
Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
  • Try loading the image using `ImageIO` rather than by using an `ImageIcon`. While `ImageIO` blocks during load, `ImageIcon` loads asynchronously. – Andrew Thompson Jan 21 '13 at 02:27
  • IIUC, `ImageIcon(url)` says "The image will be preloaded…" Internally, it uses `loadImage()`, which "Loads the image, returning only when the image is loaded." – trashgod Jan 21 '13 at 03:24
  • @trashgod Huh. OK then, my only remaining objection to it is that it will fail silently on occasions (though that is obviously not the case here). – Andrew Thompson Jan 21 '13 at 03:56
  • Ah, I hadn't seen that; thank you. Looking closer, at least one implementation handles `InterruptedException` using `System.out.println()`! – trashgod Jan 21 '13 at 04:03
3

Try this setting on g2d:-

    Map<RenderingHints.Key, Object> map = new HashMap<RenderingHints.Key, Object>();
    map.put(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
    map.put(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
    map.put(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
    RenderingHints renderHints = new RenderingHints(map);
    g2d.setRenderingHints(renderHints);
limc
  • 39,366
  • 20
  • 100
  • 145
3

Using Grid, you can mouse over the pixels to see how the alpha component rolls off at the icon's edge.

public Grid(String name) {
    this.setBackground(new Color(0xFFFFFFC0));
    Icon icon = null;
    try {
        icon = new ImageIcon(new URL("https://i.stack.imgur.com/1EZVZ.png"));
    } catch (MalformedURLException e) {
        e.printStackTrace(System.err);
    }
    ...
}

image

This IconTest shows how the icon renders with varying alpha and the default AlphaComposite.SRC_OVER rule.

enter image description here

/*** @see https://stackoverflow.com/a/14432025/230513 */
public class IconTest {

    private static final int N = 8;
    private static final Random r = new Random();

    public static void main(String[] args) throws MalformedURLException {
        final URL url = new URL("https://i.stack.imgur.com/1EZVZ.png");
        final Icon icon = new ImageIcon(url);
        EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {
                JFrame f = new JFrame("IconTest");
                f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                JPanel p = new JPanel(new GridLayout(N, N));
                for (int i = 0; i < N * N; i++) {
                    final JLabel label = new JLabel(icon);
                    label.setOpaque(true);
                    label.setBackground(new Color(0, 0, 255, i));
                    p.add(label);
                }
                f.add(p);
                f.pack();
                f.setLocationRelativeTo(null);
                f.setVisible(true);
            }
        });
    }
}
Community
  • 1
  • 1
trashgod
  • 203,806
  • 29
  • 246
  • 1,045
  • I get the same results when I run this code on my machine. So it must be something with my previous code. I'll post the entirety of it. – user1305850 Jan 21 '13 at 05:11
2

Solved. A repaint() was used in the paint() method. Removed it and it works.

Thanks for all the help.

user1305850
  • 141
  • 1
  • 2
  • 13
  • 1
    *"Solved."* Congratulations! Glad you got it sorted. :) – Andrew Thompson Jan 21 '13 at 08:25
  • @user1305850: Sorry if I was importunate. :-) The darkened image in your question reminds me of the result of repeated applications of the default `AlphaComposite.SRC_OVER` rule, so your answer seemed plausible. OTOH, you get two points for accepting another's answer! – trashgod Jan 21 '13 at 17:29