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

时间:2014-09-27 17:38:20

标签: java image swing gif animated-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通道。我不知道如何使用8位最高位作为alpha值使图像使用32位颜色模型。任何帮助表示赞赏!感谢。

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

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

1 个答案:

答案 0 :(得分:1)

我根本无法使用你的卡片来绘制图像。您的类按原样返回1,表示组件的宽度和高度。

  1. 覆盖getWidthgetHeight以返回图片大小。
  2. 请勿致电super.paintComponent() - 在这种情况下,这是多余的。
  3. drawImage接收图片最左侧最顶部的坐标,因此您只需使用0,0调用它。
  4. 此代码为我绘制alpha通道:

    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 alpha值,所以我猜您的图像存在问题......