losing transparency when using imageinputstream and bufferedimage to create png strip from gif animation

StackOverflow https://stackoverflow.com/questions/18908217

Pregunta

I was finally able to write the following code which takes a animated GIF and converts it to a png strip. however for some reason it loses the transparency from the original gif. Can someone advise how i can keep the transparency

public class Main {
public static void main(String[] args) throws IOException {
    Object input = new File("C:\\Users\\drizzt\\Documents\\jax.gif");
    // or Object input = new FileInputStream("animated.gif");
    ImageInputStream stream = ImageIO.createImageInputStream(input);
    Iterator readers = ImageIO.getImageReaders(stream);
    if (!readers.hasNext())
        throw new RuntimeException("no image reader found");
    ImageReader reader = (ImageReader) readers.next();
    reader.setInput(stream); // don't omit this line!
    int n = reader.getNumImages(true); // don't use false!
    int h = reader.getHeight(0);
    int w = reader.getWidth(0);

    BufferedImage img = new BufferedImage(w * n, h,
            BufferedImage.TYPE_INT_RGB);
    boolean[] imagedrawn;
    imagedrawn = new boolean[n];

    // big.drawImage(outputimage, w*i, 0, null);

    System.out.println("numImages = " + n);

    for (int i = 0; i < n; i++) {
        BufferedImage image = reader.read(i);
        System.out.println("image[" + i + "] = " + image);
        // img = BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
        // img.createGraphics()
        imagedrawn[i] = img.createGraphics().drawImage(image, w * i, 0,
                null);

    }

    try {
        // retrieve image
        // BufferedImage bi = getMyImage();
        File outputfile = new File("c:\\saved.png");
        ImageIO.write(img, "png", outputfile);
    } catch (IOException e) {

    }

    stream.close();
}

}

¿Fue útil?

Solución

Replace this:

BufferedImage img = new BufferedImage(w * n, h, BufferedImage.TYPE_INT_RGB);

with

BufferedImage img = new BufferedImage(w * n, h, BufferedImage.TYPE_INT_ARGB);

...and you'll have transparency.

Possibly better yet, is to do:

BufferedImage img = reader.getRawImageType(0).createBufferedImage(w * n, h);

Then you'll keep the exact image layout from the GIF, and possibly get a smaller output image (a minor detail here, is that getRawImageType may return null if there's no corresponding color space in Java, but this should probably never happen for a GIF).

Unrelated to the issue, but still good practice: Whenever you do img.createGraphics() you should also call dispose() on the Graphics2D when done painting. Move the createGraphics() outside the loop and dispose after the loop for better performance.

It's even possible to avoid the drawing altogether, and read the contents of each frame directly into img, by replacing your loop with something like this:

ImageReadParam param = reader.getDefaultReadParam();
param.setDestination(img);

for (int i = 0; i++; i < n) {
    param.setDestinationOffset(new Point(w * i, 0);
    reader.read(i, param);
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top