ImageIO.write не сохраняется как gif, но работает с jpgs и png?

Я подозреваю, что решение здесь, вероятно, действительно простое, но я в тупике ...

// Create the buffered image.
BufferedImage bufferedImage = new BufferedImage(w,h,BufferedImage.TYPE_INT_RGB);

// fill image data (works fine)
ImageIO.write(bufferedImage, "JPG", f1); // works fine
ImageIO.write(bufferedImage, "PNG", f2); // works fine
ImageIO.write(bufferedImage, "GIF", f3); // this returns false, creates a broken gif file, but fires no exceptions

Не ImageIO.write() работает для гифок? это что-то вроде возврата к тому, что gif был проприетарной вещью Compuserve? Или я просто дурак (думаю, последний :))

Ответов (2)

Решение

http://java.sun.com/javase/6/docs/api/javax/imageio/package-summary.html#gif_plugin_notes

Обратите внимание, что GIF может хранить только 256 цветов.

Чтобы расширить ответ Ини:

То, что вы должны делать, в основном, не сохранять в формате gif. GIF - это 256-цветное изображение с палитрой (отсюда и небольшой размер файла). Если ваше изображение содержит более 256 цветов, вам необходимо уменьшить разрешение цветов до 256, прежде чем пытаться сохранить. кодировщик не делает этого за вас, потому что не знает, что делать. он, вероятно, начинает писать изображение и, как только оно превысит 256 цветов, просто вылетает.

Я думаю, ты мог бы сделать это вот так (псевдокод)

// Create the buffered image.
BufferedImage bufferedImage = new BufferedImage(w,h,BufferedImage.TYPE_INT_RGB);

... //fill image data (works fine)

ImageIO.write(bufferedImage, "JPG", f1); // works fine

ImageIO.write(bufferedImage, "PNG", f2); //works fine

// downsample to lower color depth by using BYTE_RGB?
BufferedImage crappyImage = new BufferedImage(w,h,BufferedImage.TYPE_BYTE_RGB);
crappyImage.getGraphics().drawImage(bufferedImage, 0, 0, w, h, null);
// or you could repeat the drawing code above with less colors


if (!ImageIO.write(crappyImage , "GIF", f3))
{
   //still too many colors
   f3.delete();
   showError( "Could not save as gif, image had too many colors" );
}

Если ваш код рисования использует сглаживание, чтобы выглядеть красиво, это увеличит глубину цвета, даже если вы об этом не задумываетесь. Например, при рисовании диагональной синей линии AA на белом фоне может показаться, что это два цвета: Color.WHITE и Color.BLUE, но если вы присмотритесь, у вас есть целый набор оттенков синего, чтобы избавиться от них. неровный вид диагональной линии.