【问题标题】:Issue when attempting to create black and white image from previously processed image using file I/O in Java尝试使用 Java 中的文件 I/O 从先前处理的图像创建黑白图像时出现问题
【发布时间】:2015-10-03 07:22:33
【问题描述】:

我正在制作一个应用程序,它获取图像并使用文件 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.");

    }

}

【问题讨论】:

  • 您的代码有点复杂,但我看不出有任何明显的错误。你确定标题大小是 54 吗?
  • 在创建 bw 之前创建灰度版本后没有将计数器重置为 0 的事实显然存在问题,但这不应该影响第二张(灰色)图像,而不是 bw 一个,因为你会通过阈值来破坏标头
  • 是的,它真的就像在处理第二个之前将计数器设置为 0 一样简单。谢谢!
  • 我会为此创建一个答案,请标记为正确

标签: java image swing file-io jfilechooser


【解决方案1】:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-11-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-25
    • 1970-01-01
    • 2021-11-23
    • 1970-01-01
    相关资源
    最近更新 更多