用Java读取pgm文件 [英] Reading a pgm file in Java

查看:277
本文介绍了用Java读取pgm文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要读取一个pgm文件,并将其中包含的值数组存储在2D数组中. 在PGM格式中,每个像素由介于0和MaxVal之间的灰度值指定.前三行提供与图像有关的信息:幻数,高度,宽度和maxVal.该文件还包含空格.以#开头的行是注释. 这是我到目前为止所写的.

I need to read a pgm file and store the array of values contained in it in a 2D array. In PGM format, each pixel is specified by a gray value between 0 and MaxVal. The first three lines give information related to the image: magic number, height, width and maxVal. The file also includes whitespaces. Lines starting with # are comments. This is what I had written till now.

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

}
}

运行程序时,我得到以下输出:

When the program is run, I get the following output:

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

元素的数量(每个元素对应于一个灰度值)少于所需的数量.当我使用PGM查看器打开文件时,所有内容都会正确显示. 另外,当我打印数组的内容时,我看到很多负值.但是它们都必须大于或等于零. 我在哪里弄错了?

The number of elements (each corresponding to a gray value) are less than the required ones. When I open the file with a PGM viewer, everything shows up correctly. Also, when I print the contents of the array, I see a lot of negative values. But all of them have to be greater than or equal to zero. Where have I gone wrong?

推荐答案

最有可能是因为DataInputStream中不推荐使用的方法readLine().如其注释

Most likely its because of deprecated method readLine() from DataInputStream. As mentioned in its annotation

*此方法不能正确将字节转换为字符.从JDK 1.1开始,读取文本行的首选方法是通过BufferedReader.readLine()方法.通过替换以下形式的代码,可以将使用DataInputStream类读取行的程序转换为使用BufferedReader类: DataInputStream d =新的DataInputStream(in);

*This method does not properly convert bytes to characters. As of JDK 1.1, the preferred way to read lines of text is via the BufferedReader.readLine() method. Programs that use the DataInputStream class to read lines can be converted to use the BufferedReader class by replacing code of the form: DataInputStream d = new DataInputStream(in);

具有: BufferedReader d = new BufferedReader(new InputStreamReader(in)); *

with: BufferedReader d = new BufferedReader(new InputStreamReader(in));*

当我根据此建议更改程序时,它对我有用(我也做了其他几处更改:

When I changed your program according to this advice, it worked for me (I made a couple of other changes as well:

(已更新,可处理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 ;
        }

    }

这篇关于用Java读取pgm文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆