私は JAI を使用しており、次のファイルを作成します。
PlanarImage img = JAI.create("fileload", myFilename);
その行の前に、ファイルが存在するかどうかを確認します。しかし、ファイルが .bmp か .tiff か画像ファイルかを確認するにはどうすればよいでしょうか?
誰か知っていますか?
Image Magick プロジェクトには画像を識別する機能があり、JMagick と呼ばれる Image Magick の Java ラッパーがあります。
コマンドラインからの「識別」機能を含め、常にImage Magickを使用していますが、画像の識別に失敗したことは一度もありません。
その機能が絶対に必要で、JMagick がまだ存在していなかった時代に、私はJava からRuntime.exec()
ImageMagick のidentify
コマンドを使用していましたが、完全に機能しました。
JMagickが存在する現在、これはおそらくもう必要ありません(ただし、JMagickはまだ試していません)。
単なる形式以上のものを提供することに注意してください。たとえば、次のようになります。
$ identify tmp3.jpg
tmp3.jpg JPEG 1680x1050 1680x1050+0+0 DirectClass 8-bit 293.582kb
$ identify tmp.png
tmp.png PNG 1012x900 1012x900+0+0 DirectClass 8-bit 475.119kb
画像の幅を使用してみてください:
boolean isImage(String image_path){
Image image = new ImageIcon(image_path).getImage();
if(image.getWidth(null) == -1){
return false;
}
else{
return true;
}
}
幅が -1 の場合、画像ではありません。
何かが png かどうかを判断するために、Android Java で以下のスニペットを使用しました。
public CompressFormat getCompressFormat(Context context, Uri fileUri) throws IOException {
// create input stream
int numRead;
byte[] signature = new byte[8];
byte[] pngIdBytes = { -119, 80, 78, 71, 13, 10, 26, 10 };
InputStream is = null;
try {
ContentResolver resolver = context.getContentResolver();
is = resolver.openInputStream(fileUri);
// if first 8 bytes are PNG then return PNG reader
numRead = is.read(signature);
if (numRead == -1)
throw new IOException("Trying to reda from 0 byte stream");
} finally {
if (is != null)
is.close();
}
if (numRead == 8 && Arrays.equals(signature, pngIdBytes)) {
return CompressFormat.PNG;
}
return null;
}
DROIDは、Java APIも提供するファイル形式識別用のツールであり、大まかに次のように使用できます。
AnalysisController controller = new AnalysisController();
controller.readSigFile(signatureFileLocation);
controller.addFile(fileToIdentify.getAbsolutePath());
controller.runFileFormatAnalysis();
Iterator<IdentificationFile> it = controller.getFileCollection().getIterator();
APIの使用法に関するドキュメントはかなりまばらですが、この実用的な例を見ることができます(興味深い部分はidentifyOneBinary
メソッドにあります)。
ファイルの先頭には、識別文字シーケンスがあります。たとえば、JPEGファイルはFFD8FFで始まります。
プログラムでこのシーケンスを確認できますが、これがすべてのファイルで機能するかどうかはわかりません。
文字の識別については、http://filext.comをご覧ください。
ファイルの内容を判別する唯一の(半)信頼できる方法は、ファイルを開いて最初の数文字を読み取ることです。次に、Unix fileコマンドで実装されているような一連のテストを使用して、ファイルの内容について知識に基づいた推測を行うことができます。
if(currentImageType ==null){
ByteArrayInputStream is = new ByteArrayInputStream(image);
String mimeType = URLConnection.guessContentTypeFromStream(is);
if(mimeType == null){
AutoDetectParser parser = new AutoDetectParser();
Detector detector = parser.getDetector();
Metadata md = new Metadata();
mimeType = detector.detect(is,md).toString();
if (mimeType.contains("pdf")){
mimeType ="pdf";
}
else if(mimeType.contains("tif")||mimeType.contains("tiff")){
mimeType = "tif";
}
}
if(mimeType.contains("png")){
mimeType ="png";
}
else if( mimeType.contains("jpg")||mimeType.contains("jpeg")){
mimeType = "jpg";
}
else if (mimeType.contains("pdf")){
mimeType ="pdf";
}
else if(mimeType.contains("tif")||mimeType.contains("tiff")){
mimeType = "tif";
}
currentImageType = ImageType.fromValue(mimeType);
}
ビルカンの答えを拡張すると、ここで利用可能な「マジックナンバー」のリストがあります。
http://www.astro.keele.ac.uk/oldusers/rno/Computing/File_magic.html
BMP および TIFF ファイル (どちらも Windows XP / ペイントで作成されたもの) を確認したところ、正しいように見えます。
First two bytes "42 4d" -> BMP
First four bytes "4d 4d 00 2a" -> TIFF
VIM を使用してファイルを編集してから、Tools | 16 進数に変換しますが、「od -c」などを使用してチェックすることもできます。
完全な余談ですが、コンパイルされた Java クラスに使用されるマジック ナンバー ('ca fe ba be' - 'cafe babe') を見つけたとき、私は少し面白がっていました :)
標準のJavaBeans Activation Framework (JAF)を使用してみる
JavaBeans Activation Framework 標準拡張により、Java テクノロジを使用する開発者は、標準サービスを利用して、任意のデータのタイプを判別し、データへのアクセスをカプセル化し、そのデータで使用可能な操作を検出し、実行する適切な Bean をインスタンス化できます。当該操作。たとえば、ブラウザーが JPEG 画像を取得した場合、このフレームワークにより、ブラウザーはそのデータ ストリームを JPEG 画像として識別でき、その型から、ブラウザーはその画像を操作または表示できるオブジェクトを特定してインスタンス化できます。