ここでは(いつものように)単純なものが欠けているような気がします。
Javaを使用してPGMイメージを読み取ろうとしています。Matlabはそれをうまく行います-Matlabで画像ピクセル(たとえば、小さな32x32画像)を出力すると、次のようなものが得られます。
1 0 11 49 94118118106 95 88 85 96124143142133
ただし、私のJavaリーダーはこれを出力します。
1 0 11 49 94118118106 95 88 85 96124 65533 65533 65533
127を超えるピクセル値は65533で埋められているように見えますが、ランダムな値が正しくない場合があり、下の行のほぼ全体が-1の値に割り当てられています。
これが私が使用しているコードです:
filePath ='imagepath.pgm'; FileInputStream fileInputStream = new FileInputStream(filePath); BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(fileInputStream)); //ヘッダー情報を読み取ります..。 int [] [] data2D = new int [picWidth] [picHeight]; for(int row = 0; row <picHeight; row ++){ for(int col = 0; col <picWidth; col ++){ data2D [row] [col] = bufferedReader.read(); System.out.print(data2D [row] [col] + ""); } System.out.println(); } fileInputStream.close();
任意のアイデアをいただければ幸いです。
編集符号なしのPGM値は次のとおりです。
1 0 11 49 94118118106 95 88 85 96124143142133 30 26 29 57 96122125114102 94 91101127146145136 96 85 70 75101128136126111106106112131149153147 163147114 93 99120132123110113124129137154166168 215195149105 88 99114111106123148158160174191197 245224173115 81 82100109117144179194194205222230 235217170115 78 78113117100 83 80212214226244253 178167135 93 68 78123129106 77 69202204222244255 114110 92 64 54 81107105 83 59 56182184201222231 79 80 71 52 55 97 67 55 41 33 42184179181185183 62 66 65 52 63115 29 16 12 17 30209197174150132 40 47 52 44 55109171196188186208229218179136107 31 38 44 37 43 89145167158159191223219179133105 48 52 56 51 57 91128133117120157196200168128105 64 67 70 73 87114127107 79 81118159173154123104 63 67 73 83107132129 91 54 54 88130153146123106
ヘッダーは次のようになります。
P5 #MatLab PGMWRITEファイル、2002年6月27日保存 16 16 255
編集#2
以下に、概念実証コードの完全な出力を示します。
不明なトークンをスキップする: "" 不明なトークンをスキップする: "1 ^vvj_XU`|���" 不明なトークンをスキップする: "" 不明なトークンをスキップする: "9`z} rf ^ [e���`UFKe��〜ojjp������r]cx�{nq|������ÕiXcroj{�������� �sQRdmu��������٪sNNqudSP�����]DN{�jME�����rn\@ 6QkiS;8�����OPG47aC7)!*�����> BA4? s」 不明なトークンをスキップする: "" 不明なトークンをスキップする: "" 不明なトークンをスキップする:「�Ů��(/4,7m�ļ���ڳ�k」 不明なトークンをスキップする: "&、%+Y������۳�i04839[��ux��Ȩ�i@CFIWrkOQv���{h?CISk��[66X���{j" スレッド「メイン」の例外java.util.NoSuchElementException java.util.Scanner.throwFor(Scanner.java:838)で java.util.Scanner.next(Scanner.java:1347)で Test.main(Test.java:49)で
スローされた例外で参照されている49行目は次のとおりです。
System.out.println(String.format("Skipping unknow token: \"%s\"", scan.next()));
問題は、これらの画像ファイルがASCIIテキスト/数字とバイナリ画像データの両方で構成されているという事実と関係があると確信しています。しかし、JavaがPNGの読み取りに問題がない場合、なぜPGMのサポートがないのでしょうか。
編集3
わかりました、動作する実装を見つけました...残念ながら、非推奨です:
filePath = "imagepath.pgm"
FileInputStream fileInputStream = new FileInputStream(filePath);
DataInputStream dis = new DataInputStream(fileInputStream);
StreamTokenizer streamTokenizer = new StreamTokenizer(dis);
// read header text using StreamTokenizer.nextToken()
data2D = new int [picWidth] [picHeight];
for (int row = 0; row < picHeight; row++) {
for (int col = 0; col < picWidth; col++) {
data2D[row][col] = dis.readUnsignedByte();
System.out.print(data2D[row][col] + " ");
}
System.out.println();
}
Javaのドキュメントによると、メソッドがrawバイトを文字に正しく変換しないStreamTokenizer(InputStream)
ため、コンストラクターは非推奨になりました。DataInputStream.readLine()
ただし、この特定のケースではヘッダーで機能するようであり、次のバイナリイメージデータでも機能することは明らかです。
残念ながら、それはまだ非推奨でありBufferedReader
、ドキュメントが示唆しているようにaを混在させることにより、ヘッダーを読み取り、を使用して生のバイトを読み取ろEOFException
うとした後、結果はsになるだけのようです。DataInputStream
まだ解決策を探しています...