RGB value not change correctly after saving image in JAVA

荒凉一梦 提交于 2019-12-25 02:15:00

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!