JFrame使用alpha通道绘制动画gif图像



我正试图在JFrame上绘制一个动画gif图像。目前,我是这样做的:

public class JImageComponent extends JComponent {
    private static final long serialVersionUID = -6926323540532721196L;
    private final Image image;
    public JImageComponent(Image image) {
        this.image = image;
    }
    public JImageComponent(byte[] data) {
        this(Toolkit.getDefaultToolkit().createImage(data));
    }
    @Override
    protected void paintComponent(Graphics graphics) {
        super.paintComponent(graphics);
        final int centerX = getWidth() / 2 - image.getWidth(this) / 2;
        final int centerY = getHeight() / 2 - image.getHeight(this) / 2;
        graphics.drawImage(image, centerX, centerY, this);
    }
}

然而,这很好,(因为边缘有阴影)如果我有一个背景色集,它会显示一个讨厌的白色边缘。我想我知道是什么原因造成的,这是因为Image类并没有使用alpha通道。我不知道如何使图像使用32位颜色模型,使用8个最高有效位作为alpha值。感谢您的帮助!谢谢

编辑:当我尝试使用ImageIO和BufferedImage时,它没有动画。显然,这是因为它没有更新ImageObserver

编辑:这是有背景时图像的样子:http://puu.sh/bQ5sZ.png我不想要那个白边,它应该是这样的:http://puu.sh/bQ5Ya.png.就像我之前说的,我知道为什么会发生这种事;我需要Image类来使用RGBA而不是RBG。

我根本无法使用你的cade来绘制图像。您的类按原样对组件的宽度和高度都返回1。

  1. 覆盖getWidthgetHeight以返回图像的大小
  2. 不要调用super.paintComponent()——在这种情况下它是多余的
  3. drawImage接收图像的最左边、最上面的坐标,所以您可以简单地用0来调用它

这段代码为我绘制了阿尔法通道:

public class JImageComponent extends JComponent {
   private static final long serialVersionUID = -6926323540532721196L;
   private final Image image;
   public JImageComponent(Image image) {
       this.image = image;
   }
   public JImageComponent(byte[] data) {
       this(Toolkit.getDefaultToolkit().createImage(data));
   }
   @Override
   protected void paintComponent(Graphics graphics) {
       graphics.drawImage(image, 0, 0, null);
   }
   @Override
   public int getWidth() {
        return image.getWidth(null);
    }
    @Override
    public int getHeight() {
        return image.getHeight(null);
    }
}

编辑:

我之前的代码仍然显示了你的图像的白色背景,所以我挖了一个小勺并迭代每个像素:

public class JImageComponent extends JComponent {
    private static final long serialVersionUID = -6926323540532721196L;
    private final Image image;
    public JImageComponent(Image image) {
        this.image = image;
    }
    public JImageComponent(byte[] data) {
        this(Toolkit.getDefaultToolkit().createImage(data));
    }
    @Override
    protected void paintComponent(Graphics graphics) {
        Graphics2D g2 = (Graphics2D) graphics.create();
        int[] pixels = new int[image.getWidth(null)*image.getHeight(null)];
        PixelGrabber pg = 
                new PixelGrabber(image, 0, 0, image.getWidth(null), image.getHeight(null), pixels, 0, image.getWidth(null));
        try {
            pg.grabPixels();
        } catch (InterruptedException e) {
            System.err.println("interrupted waiting for pixels!");
            return;
        }
        if ((pg.getStatus() & ImageObserver.ABORT) != 0) {
            System.err.println("image fetch aborted or errored");
            return;
        }
        for (int i = 0 ; i < image.getWidth(null) ; i++) {
            for (int j = 0 ; j < image.getHeight(null) ; j++) {
                handlesinglepixel(i, j, pixels[j * image.getWidth(null) + i], g2);  
            }
        }
    }
    @Override
    public int getWidth() {
        return image.getWidth(null);
    }
    @Override
    public int getHeight() {
        return image.getHeight(null);
    }
    public void handlesinglepixel(int x, int y, int pixel, Graphics2D g2d) {
        int alpha = (pixel >> 24) & 0xff;
        int red   = (pixel >> 16) & 0xff;
        int green = (pixel >>  8) & 0xff;
        int blue  = (pixel      ) & 0xff;
        Color color = new Color(red,green,blue);
        g2d.setColor(color);
        System.out.println("Alpha value is " + (float)(alpha/255));
        g2d.setComposite(AlphaComposite.SrcAtop.derive((float)(alpha/255)));
        g2d.drawRect(x, y, 1, 1);
    }
}

这会为每个像素打印一个1.0阿尔法值,所以我想你的图像有问题。。。

最新更新