how to store jpeg image ?
I am modifying the pixel of a jpeg image using pixel grabber function and storing it using the code give below
FileOutputStream fos = new FileOutputStream("out.jpg");
JPEGImageEncoder jpeg = JPEGCodec.createJPEGEncoder(fos);
jpeg.encode(image);
fos.close();
but when i open the image using paint or any other image viewing s/w i see the image whith brown shade
also when i again perform the revese operation to get the orignal pixel value i am unable to get the orginal pixel value .
JPEG is a lossy file format: it achieves high levels of compression by throwing data away. You would have to be very lucky to get the original pixel value!
The thing about brown shade, does it happen only with one image or with all images? Have you tried using ImageIO instead of the non-standard JPEGImageEncoder?
You could try saving it as a png or gif, using ImageIO. They are not losey like jpeg.
thanks for replying ,I have even tried the given below codeImageIO.write(image, "jpeg", new File("out.jpeg"));but still the same problem occur !is there and other method to save the jpeg image without losing pixel value.
even using .gif donot solve the problem
Gif works for me. Just remember that gif uses a indexed color model. Demo:
import java.awt.*;
import java.awt.image.*;
import java.io.*;
import java.util.*;
import javax.imageio.*;
import javax.swing.*;
public class LoselessExample {
public static void main(String[] args) throws IOException {
int SIDE = 300;
BufferedImage im1 = new BufferedImage(SIDE,SIDE, BufferedImage.TYPE_BYTE_INDEXED);
WritableRaster raster1 = im1.getRaster();
DataBufferByte db1 = (DataBufferByte) raster1.getDataBuffer();
byte[] data1 = db1.getData();
new Random().nextBytes(data1);
ByteArrayOutputStream out = new ByteArrayOutputStream();
ImageIO.write(im1, "gif", out);
ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());
BufferedImage im2 = ImageIO.read(in);
WritableRaster raster2 = im2.getRaster();
DataBufferByte db2 = (DataBufferByte) raster2.getDataBuffer();
byte[] data2 = db2.getData();
boolean success = Arrays.equals(data1, data2);
System.out.println("success = " + success);
JPanel p = new JPanel();
p.add(new JLabel(new ImageIcon(im1)));
p.add(new JLabel(new ImageIcon(im2)));
JFrame f = new JFrame("LoselessExample");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setContentPane(p);
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
}
}
I believe the JPEG format spec includes a lossless mode, but it's not widely used. So the question is no, there is no way.If you want a lossless image format, PNG is a good choice. With GIF you are limited to 256 colours which may or may not be a problem.
> I believe the JPEG format spec includes a lossless> mode, but it's not widely used. But this is the perfect case for when/why to use it. So use it.
Guys, I think I know what he may be talking about.I forgot what exactly causes the problem... something to do with drawing Graphics in a BufferedImage and then saving to an image. Regardless, the solution is to always fill the background beforedrawing.
> > I believe the JPEG format spec includes a lossless
> > mode, but it's not widely used.
>
> But this is the perfect case for when/why to use it. So use it.
But don't use the plug-in jpeg writer that comes with the J2SE.
From the JavaDoc for javax.imageio.plugins.jpeg.JPEGImageWriteParam's
isCompressionLossless() method:
<quote>
Returns false since the JPEG plug-in only supports lossy compression.
</quote>
@*&^!?%#!!!
> > > I believe the JPEG format spec includes a
> lossless
> > > mode, but it's not widely used.
> >
> > But this is the perfect case for when/why to use
> it. So use it.
>
> But don't use the plug-in jpeg writer that comes with
> the J2SE.
> From the JavaDoc for
> javax.imageio.plugins.jpeg.JPEGImageWriteParam's
> isCompressionLossless() method:
>
> <quote>
> Returns false since the JPEG plug-in only supports
> lossy compression.
> </quote>
>
> @*&^!?%#!!!
True, you can however ajust the compression/quality level from the default so that you can minimize the amount of lossy
Apparently you have to install JAI for lossless JPEG: http://java.sun.com/products/java-media/jai/forDevelopers/jai-imageio-1_0-docs/overview-summary.html
Youre all still assuming he's talking about compression noise.
A "brown shade" sounds different than slight noise.
Plus the noise would probably reflect the surroundings which
would probably be brown making it look more like a blur or fuzz
than a "brown shade".
Not to mention that he said he has saved to GIF.
The picture going brown is exactly what happens with that BufferedImage problem I was talking about.
Maybe the OP could post a self-contained example like I did, eh?
can you please tell me how can i use lossless mode i.e by which method or packages in java i can create an jpeg image which causes minimum lossy compression so that most of the pixel value written on that image remains the same.can you tell me some code.
Or - and forgive my common sense - but if you dont want compression dont use a lossy format?Use PNG. ANd dont argue that. PNG is great, lol. : )
import java.awt.*;
import java.awt.image.*;
import java.io.*;
import java.util.*;
import java.net.*;
import javax.imageio.*;
import javax.swing.*;
import javax.swing.border.*;
public class LossyExample {
public static void main(String[] args) throws IOException {
URL url = new URL("http://www.gamutvision.com/docs/images/Print_test_target.png");
BufferedImage image = ImageIO.read(url);
JPanel p = new JPanel(new GridLayout(0,1));
p.add(framed(image, "original"));
for(int i = 10; i <= 100; i+=10)
p.add(framed(compress(image, i/100f), "quality=" + i + "%"));
JFrame f = new JFrame("LossyExample");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.getContentPane().add(new JScrollPane(p));
f.setSize(800,600);
f.setLocationRelativeTo(null);
f.setVisible(true);
}
static JLabel framed(BufferedImage image, String caption) {
JLabel label = new JLabel(new ImageIcon(image));
Border out = BorderFactory.createTitledBorder(caption);
Border in = BorderFactory.createEmptyBorder(10,10,10,10);
label.setBorder(BorderFactory.createCompoundBorder(out, in));
return label;
}
static BufferedImage compress(BufferedImage image, float quality) throws IOException {
ImageWriter writer = ImageIO.getImageWritersBySuffix("jpeg").next();
ImageWriteParam param = writer.getDefaultWriteParam();
param.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
param.setCompressionQuality(quality);
ByteArrayOutputStream out = new ByteArrayOutputStream();
writer.setOutput(ImageIO.createImageOutputStream(out));
writer.write(null, new IIOImage(image, null, null),param);
ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());
return ImageIO.read(in);
}
}
> Use PNG. ANd dont argue that. PNG is great, lol.
I once whipped up some code that took a given PNG image and some text,
then took each bit from the text in turn and xored it with the least-sig bit
of successive pixels from the image. Decoding the text from the resulting
image was just as easy, and when I put the original image and the one
with the hidden text side-by-side I couldn't see any difference. You know,
that poster from al-Qa'ida never gave me the dukes for that ;-()