C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[4]: java 画像ファイルの種類表示


(過去ログ 132 を表示中)

[トピック内 5 記事 (1 - 5 表示)]  << 0 >>

■77901 / inTopicNo.1)  java 画像ファイルの種類表示
  
□投稿者/ java (1回)-(2015/11/29(Sun) 14:24:45)

分類:[Java] 

javaで拡張子不明の画像ファイルを読み込みその種類を表示するプログラムを作成しているのですが下記のプログラムでPNG判定の時だけエラーが起きます.読み込みファイル名はコマンドライン引数で指定しています.PNG以外の判定をなくすとPNGはうまく判定できます.なにがおかしいのでしょうか?
import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

public class Task {

	public static void main(String args[]) {
		FileInputStream fis = null;
		BufferedInputStream bis = null;
		
		try {
			fis = new FileInputStream(args[0]);		// ファイル入力バイトストリーム
			bis = new BufferedInputStream(fis);		// 入力用バッファ
			
			/*読み込みファイルの拡張子判定に利用*/
			final byte[] BMP_SIGNATURE ={0x42, 0x4D};                         //BMP
			final byte[] JPEG_SIGNATURE ={(byte)0xFF, (byte)0xD8};            //JPEG
			final byte[] PNG_SIGNATURE ={(byte)0x89, 0x50, 0x4E, 0x47};       //PNG
			final byte[] GIF_SIGNATURE ={0x47, 0x49, 0x46, 0x38, 0x37, 0x61};//GIF
			
			
			int ch, k = 0;
			int flg1 = 0, flg2 = 0, flg3 = 0, flg4 = 0;
			
			while (((ch = bis.read()) != -1)) {	
				/*BMP判定*/
				if((byte)ch == BMP_SIGNATURE[k]) {
					flg1++;
					if(flg1 == BMP_SIGNATURE.length) {
						System.out.println(args[0] + "はBMP形式のファイルです.");
						break;
					}
				}
				/*JPEG判定*/
				if((byte)ch == JPEG_SIGNATURE[k]) {
					flg2++;
					if(flg2 == JPEG_SIGNATURE.length) {
						System.out.println(args[0] + "はJPEG形式のファイルです.");
						break;
					}
				}
				/*PNG判定*/
				if((byte)ch == PNG_SIGNATURE[k]) {
					flg3++;
					if(flg3 == PNG_SIGNATURE.length) {
						System.out.println(args[0] + "はPNG形式のファイルです.");
						break;
					}
				}
				
				/*GIF判定*/
				if((byte)ch == GIF_SIGNATURE[k] ) {
					flg4++;
					if(flg4 == GIF_SIGNATURE.length) {
						System.out.println(args[0] + "はGIF形式のファイルです.");
						break;
					}
				}
				k++;
			}
	
		} catch (FileNotFoundException e) {
			System.out.println("ファイル" + args[0] + "が見つかりません.");
			System.exit(1);
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			if (bis != null) {
				try {
					bis.close();
				} catch (IOException e) {}
			}
		}
		
	}
}

引用返信 編集キー/
■77902 / inTopicNo.2)  Re[1]: java 画像ファイルの種類表示
□投稿者/ もりお (1回)-(2015/11/29(Sun) 14:42:06)
2015/11/29(Sun) 14:42:59 編集(投稿者)

No77901 (java さん) に返信

配列の長さが違うので、たとえばkが2で、PNG_SIGNATUREの序数2の値を比較するときに
BMP_SIGNATUREの序数2の値も比較しようとしてArrayIndexOutOfBoundsExceptionが投げられそうな感じですね。
配列が長い順に比較を行ってelse ifで条件をつなげれば行けるかしら。ダメかしら。ダメかもしれません。
引用返信 編集キー/
■77903 / inTopicNo.3)  Re[2]: java 画像ファイルの種類表示
□投稿者/ java (2回)-(2015/11/29(Sun) 15:48:11)
No77902 (もりお さん) に返信
> 2015/11/29(Sun) 14:42:59 編集(投稿者)
> 
> ■No77901 (java さん) に返信
> 
> 配列の長さが違うので、たとえばkが2で、PNG_SIGNATUREの序数2の値を比較するときに
> BMP_SIGNATUREの序数2の値も比較しようとしてArrayIndexOutOfBoundsExceptionが投げられそうな感じですね。
> 配列が長い順に比較を行ってelse ifで条件をつなげれば行けるかしら。ダメかしら。ダメかもしれません。

解答ありがとうございます!下記のようにプログラムを変更してみたのですがJPEGの時だけエラーが起きてしまいますね.

while (((ch = bis.read()) != -1)) {	
				/*GIF判定*/
				if((byte)ch == GIF_SIGNATURE[k] ) {
					flg4++;
					if(flg4 == GIF_SIGNATURE.length) {
						System.out.println(args[0] + "はGIF形式のファイルです.");
						break;
					}
				}
				/*PNG判定*/
				else if((byte)ch == PNG_SIGNATURE[k]) {
					flg3++;
					if(flg3 == PNG_SIGNATURE.length) {
						System.out.println(args[0] + "はPNG形式のファイルです.");
						break;
					}
				}
				/*JPEG判定*/
				else if((byte)ch == JPEG_SIGNATURE[k]) {
					flg2++;
					if(flg2 == JPEG_SIGNATURE.length) {
						System.out.println(args[0] + "はJPEG形式のファイルです.");
						break;
					}
				}
				/*BMP判定*/
				else if((byte)ch == BMP_SIGNATURE[k]) {
					flg1++;
					if(flg1 == BMP_SIGNATURE.length) {
						System.out.println(args[0] + "はBMP形式のファイルです.");
						break;
					}
				}
				k++;
			}

引用返信 編集キー/
■77904 / inTopicNo.4)  Re[3]: java 画像ファイルの種類表示
□投稿者/ Azulean (549回)-(2015/11/29(Sun) 16:10:48)
個人的にはこの if ブロックの山でやるんじゃなくて、もっと違うアプローチを目指すべきだと思います。
どれにも一致しない場合は必ず範囲外参照の例外が発生するので。

たとえば、最長の配列は事前にわかってるのですから、そのバイト分だけ一気に読み込んでおいて、それぞれの配列の長さまでの間が一致するかどうか順に比較するとか。

No77903 (java さん) に返信
> 解答ありがとうございます!下記のようにプログラムを変更してみたのですがJPEGの時だけエラーが起きてしまいますね.

java の byte は -128 〜 127 の表現らしいですが、read の戻り値は int 型ですよね?
(byte)0xFF はおそらく int 型でいうところの -1 でしょうから、read の戻り値の 255 とは一致しませんよね?
きちんと型をそろえて比較するようにしましょう。
引用返信 編集キー/
■77905 / inTopicNo.5)  Re[4]: java 画像ファイルの種類表示
□投稿者/ java (4回)-(2015/11/29(Sun) 19:01:43)
2015/11/29(Sun) 19:03:18 編集(投稿者)
2015/11/29(Sun) 19:03:15 編集(投稿者)

No77904 (Azulean さん) に返信
> 個人的にはこの if ブロックの山でやるんじゃなくて、もっと違うアプローチを目指すべきだと思います。
> どれにも一致しない場合は必ず範囲外参照の例外が発生するので。
>
> たとえば、最長の配列は事前にわかってるのですから、そのバイト分だけ一気に読み込んでおいて、それぞれの配列の長さまでの間が一致するかどうか順に比較するとか。
>
> ■No77903 (java さん) に返信
>>解答ありがとうございます!下記のようにプログラムを変更してみたのですがJPEGの時だけエラーが起きてしまいますね.
>
> java の byte は -128 〜 127 の表現らしいですが、read の戻り値は int 型ですよね?
> (byte)0xFF はおそらく int 型でいうところの -1 でしょうから、read の戻り値の 255 とは一致しませんよね?
> きちんと型をそろえて比較するようにしましょう。

みなさんありがとうございました!指摘をもとに作成したところ完成することができました.
解決済み
引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -