读取.bmp图像并从图像的第10个字节中减去10,然后用Java重新创建图像

读取.bmp图像并从图像的第10个字节中减去10,然后用Java重新创建图像,java,image,image-processing,bmp,steganography,Java,Image,Image Processing,Bmp,Steganography,我正在创建一个应用程序,它将从.bmp图像中读取图像字节/像素/数据,并将其存储在byte/char/int/etc数组中 现在,从这个数组中,我想从数组的第10个索引中存储的数据中减去10(十进制) 我能够成功地将图像信息存储在创建的阵列中。但当我尝试将数组信息写回.bmp图像时,创建的图像不可见 这就是我试图这样做的一段代码 在这段代码中,我不是从数组的第10个索引中减去10 public class Test1 { public static void main(String[]

我正在创建一个应用程序,它将从.bmp图像中读取图像字节/像素/数据,并将其存储在byte/char/int/etc数组中

现在,从这个数组中,我想从数组的第10个索引中存储的数据中减去10(十进制)

我能够成功地将图像信息存储在创建的阵列中。但当我尝试将数组信息写回.bmp图像时,创建的图像不可见

这就是我试图这样做的一段代码

在这段代码中,我不是从数组的第10个索引中减去10

public class Test1 {

    public static void main(String[] args) throws IOException{
        File inputFile = new File("d://test.bmp");
        FileReader inputStream = new FileReader("d://test.bmp");
        FileOutputStream outputStream = new FileOutputStream("d://test1.bmp");
        /*
         * Create byte array large enough to hold the content of the file.
         * Use File.length to determine size of the file in bytes.
         */
        char fileContent[] = new char[(int)inputFile.length()];


        for(int i = 0; i < (int)inputFile.length(); i++){
            fileContent[i] = (char) inputStream.read();
        }

        for(int i = 0; i < (int)inputFile.length(); i++){
            outputStream.write(fileContent[i]);
        }
    }
}
公共类Test1{
公共静态void main(字符串[]args)引发IOException{
File inputFile=新文件(“d://test.bmp”);
FileReader inputStream=newFileReader(“d://test.bmp”);
FileOutputStream outputStream=newfileoutputstream(“d://test1.bmp”);
/*
*创建足够大的字节数组以容纳文件内容。
*使用File.length确定文件的大小(以字节为单位)。
*/
char fileContent[]=新字符[(int)inputFile.length()];
对于(int i=0;i<(int)inputFile.length();i++){
fileContent[i]=(char)inputStream.read();
}
对于(int i=0;i<(int)inputFile.length();i++){
write(fileContent[i]);
}
}
}

使用字节[]代替字符[]

如果您的代码能够正常工作,下面是一个修改版本:

public class Test {

public static void main(String[] args) throws IOException {
    File inputFile = new File("someinputfile.bmp");
    FileOutputStream outputStream = new FileOutputStream("outputfile.bmp");
    /*
     * Create byte array large enough to hold the content of the file.
     * Use File.length to determine size of the file in bytes.
     */
    byte fileContent[] = new byte[(int)inputFile.length()];


    new FileInputStream(inputFile).read(fileContent);

    for(int i = 0; i < (int)inputFile.length(); i++){
        outputStream.write(fileContent[i]);
    }

    outputStream.close();
 }
}
公共类测试{
公共静态void main(字符串[]args)引发IOException{
File inputFile=新文件(“someinputfile.bmp”);
FileOutputStream outputStream=新的FileOutputStream(“outputfile.bmp”);
/*
*创建足够大的字节数组以容纳文件内容。
*使用File.length确定文件的大小(以字节为单位)。
*/
byte fileContent[]=新字节[(int)inputFile.length()];
新文件InputStream(inputFile).read(fileContent);
对于(int i=0;i<(int)inputFile.length();i++){
write(fileContent[i]);
}
outputStream.close();
}
}

要使现有代码正常工作,应使用FileInputStream替换FileReader。根据FileReader javadoc:

FileReader用于读取字符流。若要读取原始字节流,请考虑使用FieldPixStudio。

修改您的样本如下

  public static void main(String[] args) throws IOException
 {
File inputFile = new File("d://test.bmp");
FileInputStream inputStream = new FileInputStream("d://test.bmp");
FileOutputStream outputStream = new FileOutputStream("d://test1.bmp");
/*
 * Create byte array large enough to hold the content of the file.
 * Use File.length to determine size of the file in bytes.
 */
byte fileContent[] = new byte[(int)inputFile.length()];

for(int i = 0; i < (int)inputFile.length(); i++){
    fileContent[i] =  (byte) inputStream.read();
}

inputStream.close();
for(int i = 0; i < (int)inputFile.length(); i++){
    outputStream.write(fileContent[i]);
}

outputStream.flush();
outputStream.close();
publicstaticvoidmain(字符串[]args)引发IOException
{
File inputFile=新文件(“d://test.bmp”);
FileInputStream inputStream=新的FileInputStream(“d://test.bmp”);
FileOutputStream outputStream=newfileoutputstream(“d://test1.bmp”);
/*
*创建足够大的字节数组以容纳文件内容。
*使用File.length确定文件的大小(以字节为单位)。
*/
byte fileContent[]=新字节[(int)inputFile.length()];
对于(int i=0;i<(int)inputFile.length();i++){
fileContent[i]=(字节)inputStream.read();
}
inputStream.close();
对于(int i=0;i<(int)inputFile.length();i++){
write(fileContent[i]);
}
outputStream.flush();
outputStream.close();
}

这项工作为我创建了一个原始图像的副本


尽管如上所述,这可能不是您试图实现的正确方法。

其他人指出了代码中的错误(使用
char
而不是
byte
),但是,即使您解决了这个问题,如果更改文件中第10个字节的值,您可能会得到一个不可加载的映像

这是因为,
.bmp
图像文件在任何实际图像数据之前以包含文件信息(颜色深度、尺寸等)的标题开头。具体地,第10字节是存储实际图像数据(像素阵列)的偏移的4字节整数的一部分。因此,从这个值减去10可能会使偏移指向文件中的错误点,并且图像装入器进行绑定检查可能会考虑此无效。

您真正想要做的是将图像作为图像加载,并直接操作像素值。诸如此类:

BufferedImage originalImage = ImageIO.read(new File("d://test.bmp"));
int rgb = originalImage.getRGB(10, 0);
originalImage.setRGB(rgb >= 10 ? rgb - 10 : 0);
ImageIO.write(originalImage, "bmp", new File("d://test1.bmp"));

为什么要使用
char[]
?您没有文本数据。改为使用
byte[]
。“我想从存储在数组第10个索引中的数据中减去10(十进制)。”确切的原因是什么?我想在此图像中隐藏一些信息,然后检索相同的信息。我也尝试过使用char[],但没有效果。byte fileContent[]=新字节[(int)inputFile.length()];对于(int i=0;i<(int)inputFile.length();i++){fileContent[i]=(byte)inputStream.read();}对于(int i=0;i<(int)inputFile.length();i++){outputStream.write(fileContent[i]);}outputStream.flush();outputStream.close();1) 这通常被称为。我已将标签添加到帖子中。2) 它通常不是通过改变
文件中的特定字节来实现的,而是图像或声音本身的“数据”。在这种情况下,您可以将fie读入一个
缓冲区图像
,处理图像本身,然后将其写回文件。3) 添加@JonSkeet(或任何人)以通知他们新的评论。4) 注释中的代码不可读。相反,它进入问题并使用代码格式。即使使用byte[]数组而不是char[]它仍然不起作用。您还记得关闭OutputStream吗?