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

时间:2013-02-05 09:37:32

标签: java image image-processing bmp steganography

我正在创建一个应用程序,它将从.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]);
        }
    }
}

3 个答案:

答案 0 :(得分:0)

使用byte []

代替char []

如果你的代码有效,这是修改后的版本:

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

答案 1 :(得分:0)

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

  

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

修改您的样本如下

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

}

这项工作让我可以创建原始图像的副本。

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

答案 2 :(得分:0)

其他人已经指出您的代码中存在错误(主要使用char而不是byte),但是,即使您修复了此问题,如果您可能最终会出现无法加载的图像更改文件中第10个字节的值。

这是因为,.bmp图像文件以包含有关文件的信息的标头开始(颜色深度,尺寸,...参见BMP file format),然后才能显示任何实际图像数据。具体地,第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"));