web-dev-qa-db-ja.com

PHPのbase64文字列から画像タイプを検出する

PHPでbase64文字列としてエンコードされた画像のタイプを見つけることは可能ですか?

元の画像ファイルにアクセスする方法はなく、エンコードされた文字列だけがあります。私が見たものから、imagecreatefromstring()は(base64からデコードされた後)文字列表現から画像リソースを作成できますが、画像タイプを自動的に検出し、画像リソース自体は特別なPHP表現。画像を再びファイルとして保存したい場合、保存する型が文字列表現の作成元の型に対応するかどうかはわかりません。

46
Epicurus

FileInfo はあなたのためにそれを行うことができます:

$encoded_string = "....";
$imgdata = base64_decode($encoded_string);

$f = finfo_open();

$mime_type = finfo_buffer($f, $imgdata, FILEINFO_MIME_TYPE);
97
Marc B

依存関係のためにこれらの関数を使用したくない場合は、データの最初のバイトを使用できます。

function getBytesFromHexString($hexdata)
{
  for($count = 0; $count < strlen($hexdata); $count+=2)
    $bytes[] = chr(hexdec(substr($hexdata, $count, 2)));

  return implode($bytes);
}

function getImageMimeType($imagedata)
{
  $imagemimetypes = array( 
    "jpeg" => "FFD8", 
    "png" => "89504E470D0A1A0A", 
    "gif" => "474946",
    "bmp" => "424D", 
    "tiff" => "4949",
    "tiff" => "4D4D"
  );

  foreach ($imagemimetypes as $mime => $hexbytes)
  {
    $bytes = getBytesFromHexString($hexbytes);
    if (substr($imagedata, 0, strlen($bytes)) == $bytes)
      return $mime;
  }

  return NULL;
}

$encoded_string = "....";
$imgdata = base64_decode($encoded_string);
$mimetype = getImageMimeType($imgdata);
35

@Marc Bが提供するソリューションは、私にとって最良のソリューションです(PHPバージョンが5.3.0を超える場合は、@ Aaron Murgatroydが提供するソリューションを使用できます)。

このソリューションに少し追加したいと思います。

画像タイプを取得するには、次のようにします:

$split = explode( '/', $mime_type );
$type = $split[1]; 

実際、(知らない場合)画像のMIMEタイプは次のとおりです:image/typeおよび typeは、pngまたはgifまたはjpegまたは...

それが誰かを助け、彼の解決策を@Marc Bに感謝することを願っています。

MIMEタイプの完全なリストについては、次を参照してください。

8
youssman

@Marc Bが示す方法が最も良い方法です。

FInfoが使用できない場合、私が知っている他の唯一の方法は、データをファイルに保存し、getimagesize()を実行することです。

3
Pekka 웃

ファイル形式の構造について最小限の知識がある場合は、ファイルの種類を判断できるまで、理論的にファイルの上位バイトを調べることができます。

たとえば、GIFイメージは常に次のバイトで始まりますGIF89a。ファイルの先頭でその文字列を見つけることができれば、それがGIF画像であり、他の画像形式ではないことを完全に確信できます。 (ただし、テキストファイルである可能性があります。たまたま 'GIF89a'で始まります。絶対に確実にするためには、ファイルをさらに解析する必要があります)

同様に、PNGファイルには、文字列PNGが開始点のかなり近くにあります(最初の段階ではありません。繰り返しますが、ファイル形式の詳細を調べて、知る必要がある量を判断する必要があります。確実に)。

JPEGのヘッダーには認識可能な文字列も含まれていますが、これらはより多様で複雑です。文字列Exifを探したいかもしれません。

ファイル形式の定義を取得することで間違いなくより正確になりますが、どの程度正確である必要があるかによっては、バイナリエディターでいくつかの画像ファイルを開いてその構造を確認するだけで、ファイル形式について十分に学習できます。

これらのリソースはあなたを助けるかもしれません:

2
Spudley

フォロー PHP.NET Fileinfo :-

$finfo = finfo_open(FILEINFO_MIME_TYPE); // return mime type ala mimetype extension
foreach (glob("*") as $filename) {
echo finfo_file($finfo, $filename) . "\n";
}
finfo_close($finfo);
0
Bikash Mondal