Java:在 BufferedImages 中拆分 .GIF 图像会产生格式错误的图像
Java: Splitting .GIF image in BufferedImages Gives Malformed Images
所以我有一小段代码,它以一个.gif 图像作为输入,然后将这个.gif 图像分割成一个BufferedImage 数组。之后,它将图像存储在磁盘上的数组中。当我这样做时,输出图像包含大量的白色像素噪声,这在输入 .gif 图像中是不可见的。
输入gif示例:
格式错误的输出图像示例(gif 中的第 3 帧):
我用来拆分gif的代码如下:
public static void main(String[] args) throws Exception {
splitGif(new File("C:\test.gif"));
}
public static void splitGif(File file) throws IOException {
ImageReader reader = ImageIO.getImageReadersBySuffix("gif").next(); reader.setInput(ImageIO.createImageInputStream(new FileInputStream(file)), false);
for(int i = 0; i < reader.getNumImages(true); i++) {
BufferedImage image = reader.read(i);
ImageIO.write(image, "PNG", new File(i + ".png"));
}
}
谁能帮帮我?
所以问题是,当将 .gif 文件读入 java 时,给定帧中与前一帧相比没有改变颜色的所有像素将完全透明。如果要读取 .gif 并将其拆分为正确渲染的 BufferedImages 数组,则必须用前一帧的最后一个非透明像素填充当前帧的透明像素。
代码:
public static void splitGif(File file) throws IOException {
ImageReader reader = ImageIO.getImageReadersBySuffix("gif").next();
reader.setInput(ImageIO.createImageInputStream(new FileInputStream(file)), false);
BufferedImage lastImage = reader.read(0);
ImageIO.write(lastImage, "PNG", new File(0 + ".png"));
for (int i = 1; i < reader.getNumImages(true); i++) {
BufferedImage image = makeImageForIndex(reader, i, lastImage);
ImageIO.write(image, "PNG", new File(i + ".png"));
}
}
private static BufferedImage makeImageForIndex(ImageReader reader, int index, BufferedImage lastImage) throws IOException {
BufferedImage image = reader.read(index);
BufferedImage newImage = new BufferedImage(image.getWidth(), image.getHeight(), BufferedImage.TYPE_4BYTE_ABGR);
if(lastImage != null) {
newImage.getGraphics().drawImage(lastImage, 0, 0, null);
}
newImage.getGraphics().drawImage(image, 0, 0, null);
return newImage;
}
您自己解决了这个问题,但为了良好的顺序:每个下一帧都是所有先前帧的累积,填充当前帧中的透明像素。
public static void splitGif(File file) throws IOException {
ImageReader reader = ImageIO.getImageReadersBySuffix("gif").next();
reader.setInput(ImageIO.createImageInputStream(new FileInputStream(file)), false);
BufferedImage outImage = null;
Graphics2D g = null;
for (int i = 0; i < reader.getNumImages(true); i++) {
BufferedImage image = reader.read(i);
if (g == null) {
BufferedImage outImage = new BufferedImage(image.getWidth(), image.getHeight(),
BufferedImage.TYPE_4BYTE_ABGR);
g = (Graphics2D) outImage.getGraphics();
}
g.drawImage(lastImage, 0, 0, null);
ImageIO.write(outImage, "PNG", new File(i + ".png"));
}
if (g != null) {
g.dispose();
}
}
getGraphics==createGraphics
应该是平衡的 dispose
,如文档所述。
所以我有一小段代码,它以一个.gif 图像作为输入,然后将这个.gif 图像分割成一个BufferedImage 数组。之后,它将图像存储在磁盘上的数组中。当我这样做时,输出图像包含大量的白色像素噪声,这在输入 .gif 图像中是不可见的。
输入gif示例:
格式错误的输出图像示例(gif 中的第 3 帧):
我用来拆分gif的代码如下:
public static void main(String[] args) throws Exception {
splitGif(new File("C:\test.gif"));
}
public static void splitGif(File file) throws IOException {
ImageReader reader = ImageIO.getImageReadersBySuffix("gif").next(); reader.setInput(ImageIO.createImageInputStream(new FileInputStream(file)), false);
for(int i = 0; i < reader.getNumImages(true); i++) {
BufferedImage image = reader.read(i);
ImageIO.write(image, "PNG", new File(i + ".png"));
}
}
谁能帮帮我?
所以问题是,当将 .gif 文件读入 java 时,给定帧中与前一帧相比没有改变颜色的所有像素将完全透明。如果要读取 .gif 并将其拆分为正确渲染的 BufferedImages 数组,则必须用前一帧的最后一个非透明像素填充当前帧的透明像素。
代码:
public static void splitGif(File file) throws IOException {
ImageReader reader = ImageIO.getImageReadersBySuffix("gif").next();
reader.setInput(ImageIO.createImageInputStream(new FileInputStream(file)), false);
BufferedImage lastImage = reader.read(0);
ImageIO.write(lastImage, "PNG", new File(0 + ".png"));
for (int i = 1; i < reader.getNumImages(true); i++) {
BufferedImage image = makeImageForIndex(reader, i, lastImage);
ImageIO.write(image, "PNG", new File(i + ".png"));
}
}
private static BufferedImage makeImageForIndex(ImageReader reader, int index, BufferedImage lastImage) throws IOException {
BufferedImage image = reader.read(index);
BufferedImage newImage = new BufferedImage(image.getWidth(), image.getHeight(), BufferedImage.TYPE_4BYTE_ABGR);
if(lastImage != null) {
newImage.getGraphics().drawImage(lastImage, 0, 0, null);
}
newImage.getGraphics().drawImage(image, 0, 0, null);
return newImage;
}
您自己解决了这个问题,但为了良好的顺序:每个下一帧都是所有先前帧的累积,填充当前帧中的透明像素。
public static void splitGif(File file) throws IOException {
ImageReader reader = ImageIO.getImageReadersBySuffix("gif").next();
reader.setInput(ImageIO.createImageInputStream(new FileInputStream(file)), false);
BufferedImage outImage = null;
Graphics2D g = null;
for (int i = 0; i < reader.getNumImages(true); i++) {
BufferedImage image = reader.read(i);
if (g == null) {
BufferedImage outImage = new BufferedImage(image.getWidth(), image.getHeight(),
BufferedImage.TYPE_4BYTE_ABGR);
g = (Graphics2D) outImage.getGraphics();
}
g.drawImage(lastImage, 0, 0, null);
ImageIO.write(outImage, "PNG", new File(i + ".png"));
}
if (g != null) {
g.dispose();
}
}
getGraphics==createGraphics
应该是平衡的dispose
,如文档所述。