问题
I'm trying to read an Image type JPG/JPEG to BufferedImage
, change RGB value of pixel (0,0)
Image file : http://i.upanh.com/rcfutp
but it didn't work correctly
Here is what i've try
Read image
public BufferedImage readImage1(String path)
{
BufferedImage _image = null;
BufferedImage copy = null;
try {
_image = ImageIO.read(new File(path));
copy = new BufferedImage(_image.getWidth(), _image.getHeight(), BufferedImage.TYPE_3BYTE_BGR);
copy.getGraphics().drawImage(_image, 0, 0, null);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return copy;
}
Write Image
public void writeImage1(String path,BufferedImage _image)
{
try {
ImageIO.write(_image, "jpg", new File(path));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
Client Code
BufferedImage image = readImage1("E:/2.jpg");
System.out.print((image.getRGB(0, 0))&0xFFFFFF);
System.out.print("-");
image.setRGB(0, 0, 0x00000F);
System.out.print((image.getRGB(0, 0))&0xFFFFFF);
System.out.print("-");
writeImage1("E:/3.jpg", image);
image = readImage1("E:/3.jpg");
System.out.print((image.getRGB(0, 0))&0xFFFFFF);
System.out.print return
7736127-15-5439516
I hope it was 7736127-15-15
,but it return 7736127-15-5439516
please help me to correct ,thank you very much guy
回答1:
This is not possible because of how jpg compresses data, when you are operating on every pixel of the image it is the unpacked version of the image you are operating on, the jpg format is a lossy compression format. Compressing an image then decompressing it will not yield the original image. This is why pixel values are different.
This can be clearly seen in the following image. Notice the "lines" to the right, the right side is the jpg compression then decompression of the left side.
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.awt.image.DataBufferByte;
import java.beans.Transient;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
@SuppressWarnings("serial")
public class ImageTest extends JPanel {
private BufferedImage image;
private BufferedImage saved;
public ImageTest(int w, int h) {
image = new BufferedImage(w, h, BufferedImage.TYPE_3BYTE_BGR);
randomizeImage(image);
saveAndLoadImage();
saveResultToLossLess();
}
private void saveResultToLossLess() {
BufferedImage result = new BufferedImage(image.getWidth() * 2,
image.getHeight(), BufferedImage.TYPE_3BYTE_BGR);
result.getGraphics().drawImage(image, 0, 0, null);
result.getGraphics().drawImage(saved, image.getWidth(), 0, null);
try {
ImageIO.write(result, "png", new File("comparison.png"));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
private void randomizeImage(BufferedImage image) {
// Draw a blue gradient, note that in the array below
// pixels[i] = blue, pixels[i+1] = green, pixels[i+2] = red
byte[] pixels = ((DataBufferByte) image.getRaster().getDataBuffer())
.getData();
for (int i = 0; i < pixels.length; i += 3) {
pixels[i] = (byte) (255.0 * i / pixels.length);
pixels[i + 1] = (byte) (128.0 * i / pixels.length);
pixels[i + 2] = (byte) (64.0 * i / pixels.length);
}
}
private void saveAndLoadImage() {
try {
ImageIO.write(image, "jpg", new File("image.jpg"));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
saved = ImageIO.read(new File("image.jpg"));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(image, 0, 0, null);
if (saved != null)
g.drawImage(saved, image.getWidth(), 0, null);
}
@Override
@Transient
public Dimension getPreferredSize() {
return new Dimension(image.getWidth() * 2, image.getHeight());
}
public static void main(String[] args) {
ImageTest test = new ImageTest(600, 600);
JFrame frame = new JFrame();
frame.getContentPane().add(test);
frame.pack();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
}
来源:https://stackoverflow.com/questions/20021568/rgb-value-not-change-correctly-after-saving-image-in-java