|
Description
|
When I save the subImage of BufferedImage with GIFImageWriter, the ImageWriter
write an incorrect region of the original image to a file.
I try to show the subImage on JFrame, the subImage seems like expected.
So I guess that GIFImageWriter does not work correctly.
If I use jpg/png ImageWrite, the ImageWriter will write a correct region
to a file.
- STEPS TO FOLLOW TO REPRODUCE THE PROBLEM:
OS: Windows XP SP2
JRE: 6u10, 6u11
1. Compile the following java code.
2. Run the program with a image (larger than 60x60).
- EXPECTED VERSUS ACTUAL BEHAVIOR:
EXPECTED:
Save a correct middle region (rectangular (30,30)-(60,60)) of the original file.
ACTUAL:
Save an incorrect middle region (rectangular (0,0)-(30,30)) of the original file.
For the following source code, this bug can be reproduced always.
---------- BEGIN SOURCE ----------
package test;
import java.awt.image.BufferedImage;
import java.awt.image.IndexColorModel;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.imageio.ImageWriter;
import javax.imageio.stream.FileImageOutputStream;
public class SaveSubImage extends JFrame {
/**
* inFile (GIF)
*/
private static final String IN_GIF = "./resource/image.gif";
/**
* outFile1
*/
private static final String OUT_GIF_1 = "./resource/image_sub_1.gif";
/**
* outFile2
*/
private static final String OUT_GIF_2 = "./resource/image_sub_2.gif";
/**
* imageFormat (jpg/png/gif)
*/
private static final String IMAGE_FORMAT = "gif";
/**
* main.
*
* @param args
* args
*/
public static void main(String[] args) {
try {
BufferedImage originalImage = ImageIO.read(new File(IN_GIF));
ImageWriter writer = ImageIO.getImageWritersByFormatName(
IMAGE_FORMAT).next();
// not correctly
BufferedImage subImage1 = originalImage.getSubimage(30, 30, 30, 30);
writer.setOutput(new FileImageOutputStream(new File(OUT_GIF_1)));
writer.write(subImage1);
} catch (IOException e) {
e.printStackTrace();
}
}
}
---------- END SOURCE ------------
Bug WorkaroundIf reconstructing a subImage of BufferedImage, the program will work correctly.
---------- BEGIN SOURCE ----------
// correctly
BufferedImage subImage2 = originalImage.getSubimage(30, 30, 30, 30);
BufferedImage subImage3 = new BufferedImage(subImage2.getHeight(),
subImage2.getWidth(), subImage2.getType(),
(IndexColorModel) subImage2.getColorModel());
subImage3.setData(subImage2.getData());
writer.setOutput(new FileImageOutputStream(new File(OUT_GIF_2)));
writer.write(subImage3);
---------- END SOURCE ------------
Posted Date : 2009-01-20 09:00:13.0
|
|
Evaluation
|
The reason of problem here is that the optimized writing loop (utilized
direct access to image data buffer) does not take into account a data
band offset (which is non-trivial for sub-images, for example). It results
in writing image data starting from top left corner of the parent image
instead of expected top left corner of the sub-image.
We should take into account data bands offset, calculated by translated
raster instance.
Posted Date : 2009-01-21 13:11:46.0
|