Reputation: 3
I'm trying to draw an animated gif image on a JFrame. At the moment, this is how I'm doing it:
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);
}
}
This is fine, however, (because there's shading on the edge) if i have a background colour set, it shows a nasty white edge. I think i know what's causing this, it's because of the the Image class does not utilise an alpha channel. I don't know how to make the image use a 32-bit colour model using the 8 most significant bits as the alpha value. Any help is appreciated! Thanks.
Edit: when I tried using a ImageIO and a BufferedImage, it didn't animate. Apparently this is because it doesn't update the ImageObserver
Edit: This is what the image looks like when there's a background: http://puu.sh/bQ5sZ.png I don't want that white edge, it should look like this: http://puu.sh/bQ5Ya.png. Like i said previously, i know why it's happening; I need the Image class to use RGBA not RBG.
Upvotes: 0
Views: 405
Reputation: 5533
I couldn't use your cade to draw an image at all. Your class, as is, returns 1 for both the width and height of the component.
getWidth
and getHeight
to return the size of the image.super.paintComponent()
- it's redundant in this case.drawImage
receives the left-most, top-most coordinate of the image, so you can simply call it with 0, 0.This code draws alpha channel right for me:
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);
}
}
EDIT:
My previous code still showed a white background for your image, so I dig a little dipper and iterate each pixel:
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);
}
}
This prints a 1.0
alpha value for every pixel, so I guess there's a problem with your image...
Upvotes: 1