阅读Java中的PGM文件(Reading a pgm file in Java)

2019-09-21 04:14发布

我需要阅读PGM文件,并存储在一个二维数组包含的值的数组。 在PGM格式中,每个像素由0和MaxVal最大值之间的灰度值指定。 前三行给出相关的所述图像信息:幻数,高度,宽度和MAXVAL。 该文件还包括空格。 以#开头的行是注释。 这是我写至今。

public class PGM{

public static void main(String args[]) throws Exception {
    FileInputStream f = new FileInputStream("C:\\......\\brain_001.pgm");
    DataInputStream d = new DataInputStream(f);
    d.readLine();//first line contains P5
    String line = d.readLine();//second line contains height and width
    Scanner s = new Scanner(line);
    int width = s.nextInt();
    int height = s.nextInt();
    line = d.readLine();//third line contains maxVal
    s = new Scanner(line);
    int maxVal = s.nextInt();
    byte[][] im = new byte[height][width];
    for (int i = 0; i < 258; i++) {
        for (int j = 0; j < 258; j++) {
            im[i][j] = -1;
        }
    }
    int count = 0;
    byte b;
    try {
        while (true) {
            b = (byte) (d.readUnsignedByte());
            if (b == '\n') { //do nothing if new line encountered
            } else if (b == '#') {
                d.readLine();
            } else if (Character.isWhitespace(b)) { // do nothing if whitespace encountered
            } else {
                im[count / width][count % width] = b;
                count++;
            }
        }
    } catch (EOFException e) {
    }
    System.out.println("Height=" + height);
    System.out.println("Width=" + height);
    System.out.println("Required elemnts=" + (height * width));
    System.out.println("Obtained elemnets=" + count);

}
}

当程序运行时,我得到下面的输出:

Height=258
Width=258
Required elemnts=66564
Obtained elemnets=43513

元件(每一个对应于灰度值)的数量是小于所需的。 当我打开了PGM器打开,一切都显示正确。 此外,当我打印数组的内容,我看到了很多负值。 但是,所有的人都必须大于或等于零。 我在哪里出了错?

Answer 1:

最有可能的,因为不建议使用的方法readLine()DataInputStream 。 正如它的注释中提到

*此方法不正确地将字节转换为字符。 作为JDK 1.1,阅读文本行的首选方法是使用BufferedReader.readLine()方法。 使用该DataInputStream类读取文本行的程序可以被转换通过更换形式的代码来使用BufferedReader类:(上)DataInputStream所d =新DataInputStream类;

用:的BufferedReader d =新的BufferedReader(新的InputStreamReader(在)); *

当我按照这个建议改变你的程序,它为我工作(我做了一些其他的变化,以及:

更新处理PGM的P2和P5口味

    public static void main(String args[]) throws Exception {
        try {
            InputStream f = ClassLoader.getSystemClassLoader().getResourceAsStream("lena.pgm");
            BufferedReader d = new BufferedReader(new InputStreamReader(f));
            String magic = d.readLine();    // first line contains P2 or P5
            String line = d.readLine();     // second line contains height and width
            while (line.startsWith("#")) {
                line = d.readLine();
            }
            Scanner s = new Scanner(line);
            int width = s.nextInt();
            int height = s.nextInt();
            line = d.readLine();// third line contains maxVal
            s = new Scanner(line);
            int maxVal = s.nextInt();
            byte[][] im = new byte[height][width];

            int count = 0;
            int b = 0;
            try {
                while (count < height*width) {
                    b = d.read() ;
                    if ( b < 0 ) 
                        break ;

                    if (b == '\n') { // do nothing if new line encountered
                    } 
//                  else if (b == '#') {
//                      d.readLine();
//                  } 
//                  else if (Character.isWhitespace(b)) { // do nothing if whitespace encountered
//                  } 
                    else {
                        if ( "P5".equals(magic) ) { // Binary format
                            im[count / width][count % width] = (byte)((b >> 8) & 0xFF);
                            count++;
                            im[count / width][count % width] = (byte)(b & 0xFF);
                            count++;
                        }
                        else {  // ASCII format
                            im[count / width][count % width] = (byte)b ;
                            count++;
                        }
                    }
                }
            } catch (EOFException eof) {
                eof.printStackTrace(System.out) ;
            }
            System.out.println("Height=" + height);
            System.out.println("Width=" + height);
            System.out.println("Required elements=" + (height * width));
            System.out.println("Obtained elements=" + count);
        }
        catch(Throwable t) {
            t.printStackTrace(System.err) ;
            return ;
        }

    }


Answer 2:

下面的代码对我的作品:

FileInputStream f;
    try {
        f = new FileInputStream(fileLocation);
        BufferedReader br = new BufferedReader(new InputStreamReader(f));
        String magic = br.readLine();    // first line contains P2 or P5
        String line = br.readLine();     // second line contains height and width

        //-scan width and height
        Scanner s = new Scanner(line);
        int width = s.nextInt();
        int height = s.nextInt();
        s.close();

        //-scan max value
        line = br.readLine();// third line contains maxVal
        s = new Scanner(line);
        //          int maxVal = s.nextInt();
        //-close scanner
        s.close();
        //-close buffer
        br.close();
        f.close();

        xvec=new DenseMatrix64F(height*width, 1);

        int b=0;
        int counter=0;
        f = new FileInputStream(fileLocation);
        DataInputStream dis = new DataInputStream(f);
        //-move across unused lines
        dis.readLine();
        dis.readLine();
        dis.readLine();
        while ((b=dis.read()) >= 0) {
            xvec.set(counter, 0, b);
            counter++;
        }
        dis.close();
    } catch (FileNotFoundException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }


文章来源: Reading a pgm file in Java
标签: java pgm