jpeg has poor quality when written back to disk  
Author Message
code_wrong





PostPosted: 2004-4-22 4:19:00 Top

java-programmer, jpeg has poor quality when written back to disk Hi,
I have written an app using netbeans that loads a jpeg image to a panel.
I can then do some processing on it. However if I do no
processing other than loading the file and saving it as a jpeg,
the file has very bad quality. (compressed further?)

How can I save an image file (jpeg) without losing quality?


 
code_wrong





PostPosted: 2004-4-22 6:47:00 Top

java-programmer >> jpeg has poor quality when written back to disk
"Roedy Green" <email***@***.com> wrote in message
news:email***@***.com...
> On Wed, 21 Apr 2004 21:19:29 +0100, "code_wrong" <email***@***.com>
> wrote or quoted :
>
> >How can I save an image file (jpeg) without losing quality?
>
> Jpeg is a "lossy" compressed format with varying degrees of
> compression. I suggest you look for methods that let you find out how
> much you had to start, and that let you control how much to use on
> save. Then you can use the same.
>
> See http://mindprod.com/jgloss/jpegencoder.html

Thanks . after a fair bit of googling I found this:
http://javaalmanac.com/egs/javax.imageio/JpegWrite.html
e699. Compressing a JPEG File
This example implements a method for writing a JPEG file with a specific
compression quality. In J2SE 1.4, the compression capability is not
functioning properly. This example demonstrates a workaround.

// Reads the jpeg image in infile, compresses the image,
// and writes it back out to outfile.
// compressionQuality ranges between 0 and 1,
// 0-lowest, 1-highest.
public void compressJpegFile(File infile, File outfile, float
compressionQuality) {
try {
// Retrieve jpg image to be compressed
RenderedImage rendImage = ImageIO.read(infile);

// Find a jpeg writer
ImageWriter writer = null;
Iterator iter = ImageIO.getImageWritersByFormatName("jpg");
if (iter.hasNext()) {
writer = (ImageWriter)iter.next();
}

// Prepare output file
ImageOutputStream ios = ImageIO.createImageOutputStream(outfile);
writer.setOutput(ios);

// Set the compression quality
ImageWriteParam iwparam = new MyImageWriteParam();
iwparam.setCompressionMode(ImageWriteParam.MODE_EXPLICIT) ;
iwparam.setCompressionQuality(compressionQuality);

// Write the image
writer.write(null, new IIOImage(rendImage, null, null), iwparam);

// Cleanup
ios.flush();
writer.dispose();
ios.close();
} catch (IOException e) {
}
}

// This class overrides the setCompressionQuality() method to workaround
// a problem in compressing JPEG images using the javax.imageio package.
public class MyImageWriteParam extends JPEGImageWriteParam {
public MyImageWriteParam() {
super(Locale.getDefault());
}

// This method accepts quality levels between 0 (lowest) and 1 (highest)
//and simply converts
// it to a range between 0 and 256; this is not a correct conversion
algorithm.
// However, a proper alternative is a lot more complicated.
// This should do until the bug is fixed.
public void setCompressionQuality(float quality) {
if (quality < 0.0F || quality > 1.0F) {
throw new IllegalArgumentException("Quality out-of-bounds!");
}
this.compressionQuality = 256 - (quality * 256);
}
}