将byte []数组转换为BufferedImage对象

问题描述 投票:0回答:1

我已将图像拍摄到BufferedImage对象中。现在,我已将数组转换为字节数组。我想修改字节数据,然后打印新图像。这种转换在BufferedImage中提供了我的空对象。还请告诉我图像是如何存储在单个三维字节数组中的,因为根据我的观点,一个3 * 3图像的大小必须接近9,但令人震惊的是:672bytes

请帮助我。

我尝试了谷歌搜索。看到别人的代码。

import java.io.*;
import javax.imageio.ImageIO;
import java.awt.*;
import javax.swing.*;
import java.awt.image.*;
class SVisualizer{
    JFrame f;
    JLabel l;
    SVisualizer(){
        f=new JFrame("SVisualizer");
        f.setLayout(new FlowLayout());
        f.setLocationRelativeTo(null);
        f.setSize(590, 428);
        f.setResizable(false);
        f.setDefaultCloseOperation(f.EXIT_ON_CLOSE);    
    }
    public byte[] inputImage(){
        try{
        File file=new File("C:/Users/sanss/OneDrive/Desktop/1.jpg");
        BufferedImage bufferedImage = ImageIO.read(file);
        ByteArrayOutputStream baos=new ByteArrayOutputStream();
        ImageIO.write(bufferedImage, "jpg", baos);
        return baos.toByteArray();
        }
        catch(Exception e){
            System.out.println("Image cannot be processed!?");
        }
        return null;
    }
    public BufferedImage outputImage(byte[]data){
        try{
         ByteArrayInputStream bis = new ByteArrayInputStream(data);
         BufferedImage bImage = ImageIO.read(bis);
         return bImage;
        }
        catch(Exception e){
            System.out.println("Error while parsing array!?");
        }
        return null;
    }
    public int[] setWeight(int n){
        int[] data=new int[n];
        for(int i=0;i<n;i++)
            data[i]=i;
        return data;
    }
    public void setRandom(byte[] data, int[] weight){
        //back to front and front to back, simple randomisation
        int n=data.length;
        for(int i=0;i<n/2;i++){
            byte temp1=data[i];
            int temp2=weight[i];
            data[i]=data[n-1-i];
            weight[i]=data[n-1-i];
            data[n-i-1]=temp1;
            weight[n-i-1]=temp2;
        }
    }
    public void setImage(BufferedImage bImage){
        ImageIcon imageIcon=null;
        try{
        imageIcon=new ImageIcon(bImage);
        f.setContentPane(new JLabel(imageIcon));
        f.setVisible(true);
        }
        catch(Exception e){
            System.out.println("Error in setImage");
            System.out.println("BufferedImage: "+bImage);
            System.out.println("ImageIcon: "+imageIcon);
        }
    }
    public void printByteArray(byte[]data){
        for(int i=0;i<data.length;i++)
            System.out.println(data[i]+" ");
    }
    /*
    public void bubbleSort(byte[] data, int[] weight){
        int n=data.length;
        BufferedImage finalImage=outputImage(data);
        for(int i=0;i<n;i++){
            for(int j=0;j<n-1-i;j++){

            }
        }
    }*/
    public static void main(String args[]){
        SVisualizer ob=new SVisualizer();
        byte[] array=ob.inputImage();
        int[] weight=ob.setWeight(array.length);
        ob.setRandom(array, weight);
        BufferedImage oImage=ob.outputImage(array);
        ob.setImage(oImage);
        //ob.printByteArray(array);
        System.out.println(array.length);
    }
}
java image-processing bufferedimage
1个回答
1
投票

JPEG的字节不是像素。 JPEG是一种压缩的(通常是有损的)格式。直接修改字节将破坏压缩数据,从而导致文件不再兼容,不再是有效的JPEG图像。

要将图像像素转换为字节数组,您需要从BufferedImage中读取原始像素数据。为此,您首先必须确定每个字节值的含义。一种常见的方法是使用四个字节存储每个像素:一个用于像素颜色的红色分量,一个用于绿色分量,一个用于蓝色分量,以及一个用于alpha(透明度)分量。这通常是RGBA的缩写。

许多其他配置也是可能的。例如,如果您的图像是灰度的,则只需将每个像素的灰度值存储在一个字节中即可。

如果采用第一种方法,则可以使用getRGB method of BufferedImage来检索值:

int width = bImage.getWidth();
int height = bImage.getHeight();

byte[] bytes = new byte[width * height * 4];
ByteBuffer buffer = ByteBuffer.wrap(bytes);
IntBuffer intBuffer = buffer.asIntBuffer();

int[] rowPixels = new int[width];
for (int y = 0; y < height; y++) {
    bImage.getRGB(0, y, width, 1, rowPixels, 0, width);
    intBuffer.put(rowPixels);
}

return bytes;

您可以使用setRGB将字节转换回图像:

ByteBuffer buffer = ByteBuffer.wrap(data);
IntBuffer intBuffer = buffer.asIntBuffer();

BufferedImage bImage = new BufferedImage(width, height,
    BufferedImage.TYPE_INT_ARGB);

int[] rowPixels = new int[width];
for (int y = 0; y < height; y++) {
    intBuffer.get(rowPixels);
    bImage.setRGB(0, y, width, 1, rowPixels, 0, width);
}

关于一维数组如何保存像素:图像格式将指定如何。通常,像素的每一行都出现在数组的前一行之后。数组中每行开始之间的确切字节数称为扫描线跨度。

© www.soinside.com 2019 - 2024. All rights reserved.