NSDataオブジェクトのMIMEタイプをどのように決定しますか?私はユーザーにiPhoneからビデオ/画像をアップロードしてもらい、そのファイルをNSDataクラスでラップすることを計画しています。
NSDataからMIMEタイプを判別できるかどうか疑問に思っていました。この質問に対する回答はほんのわずかで、最新の回答は2010年(4年前!)からです。ありがとう!
NSData *data; // can be an image or video
NSString *mimeType = [data getMimetype]; // how would I implement getMimeType
同様の投稿からのmlの回答 に基づいて、NSDataのMIMEタイプの決定を追加しました。
ObjC:
+ (NSString *)mimeTypeForData:(NSData *)data {
uint8_t c;
[data getBytes:&c length:1];
switch (c) {
case 0xFF:
return @"image/jpeg";
break;
case 0x89:
return @"image/png";
break;
case 0x47:
return @"image/gif";
break;
case 0x49:
case 0x4D:
return @"image/tiff";
break;
case 0x25:
return @"application/pdf";
break;
case 0xD0:
return @"application/vnd";
break;
case 0x46:
return @"text/plain";
break;
default:
return @"application/octet-stream";
}
return nil;
}
迅速:
static func mimeType(for data: Data) -> String {
var b: UInt8 = 0
data.copyBytes(to: &b, count: 1)
switch b {
case 0xFF:
return "image/jpeg"
case 0x89:
return "image/png"
case 0x47:
return "image/gif"
case 0x4D, 0x49:
return "image/tiff"
case 0x25:
return "application/pdf"
case 0xD0:
return "application/vnd"
case 0x46:
return "text/plain"
default:
return "application/octet-stream"
}
}
これはメインのファイルタイプのみを処理しますが、ニーズに合わせて完了することができます。すべてのファイルシグネチャが利用可能です ここ 、ちょうど私がしたのと同じパターンを使用します。
PS:対応するすべてのMIMEタイプを使用できます ここ
❤️スイフト
extension Data {
private static let mimeTypeSignatures: [UInt8 : String] = [
0xFF : "image/jpeg",
0x89 : "image/png",
0x47 : "image/gif",
0x49 : "image/tiff",
0x4D : "image/tiff",
0x25 : "application/pdf",
0xD0 : "application/vnd",
0x46 : "text/plain",
]
var mimeType: String {
var c: UInt8 = 0
copyBytes(to: &c, count: 1)
return Data.mimeTypeSignatures[c] ?? "application/octet-stream"
}
}
私の知る限り、NSData
はバイト配列をラップする単なるデータオブジェクトです。
...そのMIMEタイプを発見したい場合、私は、バイト自体を検査し、そこからタイプを推測することを考えることができます。その例がここにあります: NSDataまたはUIImageから画像タイプを検索
私もこれを見つけました: ファイルからロードされたNSDataのMIMEタイプを判別 ;これは、MIMEタイプの検索に使用できる内部データベース(おそらく)を参照しています。
しかし、トム・ハリントンが彼の答えで言うように、あなたが何を扱っているかによってそれはトリッキーになるかもしれません。
編集...
もちろん、その2番目の解決策は、明らかにないファイル拡張子に依存していますが、すでにそれに気付いていると思います。
あなたがploadingこのデータであると言うので、MIMEタイプを知っているはずです。データオブジェクトを作成し、データがどこから来たかがわかっていて、MIMEタイプの数が限られている。したがって、データに当てはまる方を使用してください。画像の場合、おそらくimage/jpeg
またはimage/png
です。動画の場合、video/
タイプがたくさんあります。 Macの/etc/Apache2/mime.types
に、MIMEタイプの文字列の長いリストがあります。あなたが持っているビデオの種類に応じてそれらの1つ以上が必要になります。
MIMEタイプの判別は厄介な問題です。 NSData
は、あらゆる種類のバイナリデータをエンコードできます。エンコードされたものを判別する唯一の方法は、バイトを調べることです。つまり、さまざまなファイルタイプに存在するバイトストリームについてある程度理解する必要があります。多くの場合(すべてではない)でルックアップディクショナリを使用できるはずです。また、一般的なファイルタイプのどこかにオープンソースの実装がある場合があります。何が関係しているかを理解するには、Macでman file
を試して/usr/share/file/magic/
を調べ、さまざまなファイルタイプがどのように識別されるかを確認します(file
コマンドはMIMEタイプを生成しませんが、はファイルの内容を分析してファイルの種類を特定しますので、同じ原理です)。
var values = [UInt8](repeating:0、count:imgData.count)
imgData.copyBytes(to:&values、count:1)
switch values {
case 0xff:
return "image/jpeg"
case 0x89:
return "image/png"
case 0x47:
return "image/gif"
case 0x49, 0x4d:
return "image/tiff"
}
return ""