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

在JAVA中保存图像后,RGB值未正确更改,java,image,rgb,bufferedimage,Java,Image,Rgb,Bufferedimage,我正在尝试将图像类型JPG/JPEG读取到buffereImage,更改像素(0,0)的RGB值 图像文件: 但它没有正常工作 以下是我尝试的 读取图像 public BufferedImage readImage1(String path) { BufferedImage _image = null; BufferedImage copy = null; try { _image = ImageIO.read(ne

我正在尝试将图像类型JPG/JPEG读取到
buffereImage
,更改像素(0,0)的RGB值
图像文件:
但它没有正常工作
以下是我尝试的
读取图像

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);
系统输出返回

7736127-15-5439516
我希望它是
7736127-15-15
,但它返回
7736127-15-5439516

请帮助我更正,非常感谢guy

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

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

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

导入java.awt.Dimension;
导入java.awt.Graphics;
导入java.awt.image.buffereImage;
导入java.awt.image.DataBufferByte;
导入java.beans.Transient;
导入java.io.File;
导入java.io.IOException;
导入javax.imageio.imageio;
导入javax.swing.JFrame;
导入javax.swing.JPanel;
@抑制警告(“串行”)
公共类ImageTest扩展了JPanel{
私有缓冲图像;
保存私有缓冲区图像;
公共图像测试(int w,int h){
image=新的buffereImage(w,h,buffereImage.TYPE_3BYTE_BGR);
随机图像(图像);
saveAndLoadImage();
saveResultToLossLess();
}
私有void saveResultToLossLess(){
BuffereImage结果=新的BuffereImage(image.getWidth()*2,
image.getHeight(),buffereImage.TYPE_3BYTE_BGR);
result.getGraphics().drawImage(image,0,0,null);
result.getGraphics().drawImage(已保存,image.getWidth(),0,null);
试一试{
write(结果“png”,新文件(“comparison.png”);
}捕获(IOE异常){
//TODO自动生成的捕捉块
e、 printStackTrace();
}
}
私有void randomizeImage(BuffereImage图像){
//画一个蓝色渐变,注意下面的数组中
//像素[i]=蓝色,像素[i+1]=绿色,像素[i+2]=红色
字节[]像素=((DataBufferByte)image.getRaster().getDataBuffer())
.getData();
对于(int i=0;i
1)要更快地获得更好的帮助,请发布一个。2) 例如,获取图像的一种方法是热链接到中看到的图像。更新的先生,谢谢,我不擅长英语,很高兴等待您的帮助,我已经为此工作了两周,非常累…@user1747373我在处理图像时遇到了类似的问题。我没有使用JAVA,但最终遇到了类似的问题。我最终发现这与JPEG在保存时的压缩方式有关。“很高兴等待您的帮助”很高兴您喜欢它,但我仍在等待看到SSCCE。因此,在chrome中,右键单击图像并在新选项卡中打开。好的,现在我得到了,先生:D非常感谢。这意味着无法使用JPG/JPEG文件?不,不幸的是,不能。您仍然可以使用JPEG隐藏数据,这是完全可能的,但我建议您打开另一个问题,专门寻求帮助,了解您正在尝试实现的目标,而不是您正在尝试实现的目标。祝你的项目好运