在JAVA中保存图像后,RGB值无法正确更改

时间:2013-11-16 17:39:39

标签: java image rgb bufferedimage

我正在尝试将图像类型JPG / JPEG读取到BufferedImage,更改像素(0,0)的RGB值
图片文件:http://i.upanh.com/rcfutp
但它没有正常工作
这是我尝试过的 阅读图片

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;
    }

写图片

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();
        }
    }

客户代码

    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

我希望它是7736127-15-15,但它会返回7736127-15-5439516 请帮我纠正,非常感谢你

1 个答案:

答案 0 :(得分:1)

这是不可能的,因为jpg如何压缩数据,当你在图像的每个像素上操作它是你正在操作的图像的解压缩版本时,jpg格式是一种有损压缩格式。压缩图像然后解压缩它将不会产生原始图像。这就是像素值不同的原因。

这可以在下图中清楚地看到。注意右边的“线”,右边是jpg压缩,然后是左侧的解压缩。

enter image description here

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);
    }
}