尝试使用 Java 中的文件 I/O 从先前处理过的图像创建黑白图像时出现问题

Issue when attempting to create black and white image from previously processed image using file I/O in Java

我正在制作一个应用程序,该应用程序使用文件 i/o 拍摄图像并对其应用灰度滤镜。然后要求用户提供一个阈值和另一个保存位置,该位置将采用此处理后的图像并使其成为纯黑白。我遇到的问题是当创建第二张图像并尝试打开它时,Windows 报告文件已损坏,即使文件大小与处理后的图像相同,所以它似乎工作正常。这是我的应用程序代码。我还想继续使用文件 IO 来创建它,我知道 Java 有一个用于创建二进制图像的内置函数。

import java.io.*;
import javax.swing.*;

public class Bitmapper
{
    public static void main(String[] args)
    {
        String threshold;
        int thresholdInt;
        JFileChooser chooser1 = new JFileChooser();
        JFileChooser chooser2 = new JFileChooser();
        JFileChooser chooser3 = new JFileChooser();
        int status1 = chooser1.showOpenDialog(null);
        int status2 = chooser2.showSaveDialog(null);
        if(status1 == JFileChooser.APPROVE_OPTION && status2 == JFileChooser.APPROVE_OPTION)
        {

            try
            {
                // Handling binary (not text) data, so use FileInputStream
                FileInputStream in  = new FileInputStream(chooser1.getSelectedFile());
                FileOutputStream out = new FileOutputStream(chooser2.getSelectedFile() + "_gray.bmp");

                int i = 0;
                int counter = 0;


                while((i=in.read())!=-1) 
                {
                    if (++counter>54)   // skip past Bitmap headers
                    {
                        int b = i;
                        int g = in.read();
                        int r = in.read();

                        int gray = (b + g + r)/3;

                        out.write(gray);
                        out.write(gray);
                        i = gray;
                    }
                    out.write(i);
                }

                out.close();
                in.close();
                threshold = JOptionPane.showInputDialog(null, "Please enter a threshold to turn the picture black and white.");

                try
                {
                    thresholdInt = Integer.parseInt(threshold);
                    int status3 = chooser3.showSaveDialog(null);
                    if(status3 == JFileChooser.APPROVE_OPTION)
                    {
                        in = new FileInputStream(chooser2.getSelectedFile() + "_gray.bmp");
                        out = new FileOutputStream(chooser3.getSelectedFile() + "_bw.bmp");
                        while((i=in.read())!=-1) 
                        {
                            if (++counter>54)   // skip past Bitmap headers
                            {
                                int b = i;
                                int g = in.read();
                                int r = in.read();

                                if(b > thresholdInt)
                                    out.write(0);
                                else
                                    out.write(255);

                                if(g > thresholdInt)
                                    out.write(0);
                                else
                                    out.write(255);

                                if(r > thresholdInt)
                                    i = 0;
                                else
                                    i = 255;

                            }
                            out.write(i);
                        }

                    }
                    else
                        JOptionPane.showMessageDialog(null, "You did not select a save location for the second image.");
                } 

                catch(NumberFormatException ex){
                    JOptionPane.showMessageDialog(null, "Issue with user input, ensure you entered an integer. Error: " + ex);
                }



            }
            catch(IOException ex)
            {
                JOptionPane.showMessageDialog(null,"Error in input/output of file:" + " '" + ex + "'");
            }

        }
        else
            JOptionPane.showMessageDialog(null,"You did not specify a file or a save location for the new file.");

    }

}

你的问题是你没有在创建 _gray 图像之后,在创建 _bw 图像之前将计数器变量重置为 0。因此,您正在读取/写入 headers 作为颜色字节,对它们进行阈值处理并破坏它们。重置它应该可以解决它。