Определение типа изображения из строки base64 в PHP - PullRequest
44 голосов
/ 19 мая 2011

Можно ли узнать тип изображения, закодированного в виде строки base64 в PHP?

У меня нет способа доступа к исходному файлу изображения, только закодированная строка.Из того, что я видел, imagecreatefromstring() может создать ресурс изображения из строкового представления (после того, как он был декодирован из base64), но он автоматически определяет тип изображения, а сам ресурс изображения является специальным представлением PHP.Если я захочу снова сохранить изображение в виде файла, я понятия не имею, соответствует ли тип, в котором я его сохраняю, исходному типу, из которого было создано представление String.

Ответы [ 6 ]

95 голосов
/ 19 мая 2011

FileInfo может сделать это для вас:

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

$f = finfo_open();

$mime_type = finfo_buffer($f, $imgdata, FILEINFO_MIME_TYPE);
34 голосов
/ 28 марта 2012

Если вы не хотите использовать эти функции из-за их зависимостей, вы можете использовать первые байты данных:

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);
8 голосов
/ 02 сентября 2014

Решение, данное @Marc B, является лучшим для меня (если наша версия php> 5.3.0, в противном случае мы можем использовать решение, данное @Aaron Murgatroyd).

Я бы хотел немного дополнить это решение.

Чтобы получить тип изображения, вы можете сделать это так:

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

На самом деле (если вы этого не знаете) тип mime для изображений: image / type и type может быть png или gif или jpeg или ...

Надеюсь, что это может кому-то помочь, и спасибо @Marc B. за его решение.

Полный список типов пантомимы вы можете посмотреть здесь:

3 голосов
/ 19 мая 2011

Путь, показанный @Marc B, самый хороший.

Если FInfo недоступен, я знаю только один способ - сохранить данные в файл и запустить getimagesize() наэто.

2 голосов
/ 19 мая 2011

Если вы знаете минимальное количество о структуре формата файла, вы можете теоретически просматривать верхние байты файла, пока не сможете определить, какой это тип файла.

Например, изображение GIF всегда начинается со следующих байтов GIF89a. Если вы можете найти эту строку в начале файла, вы можете быть достаточно уверены, что это изображение в формате GIF и абсолютно уверены, что это не какой-либо другой формат изображения. (хотя это все же может быть текстовый файл, который, как правило, начинается с «GIF89a»; вам нужно проанализировать больше файлов, чтобы быть абсолютно уверенным)

Аналогично, PNG-файлы имеют строку PNG довольно близко к началу (это не совсем в самом начале; опять же, вам нужно изучить особенности формата файла, чтобы помочь вам определить, сколько вам нужно знать чтобы быть уверенным).

JPEG также содержат узнаваемые строки в своих заголовках, хотя они более разнообразны и сложны. Возможно, вы захотите посмотреть на строку Exif.

Получение определений форматов файлов определенно даст вам больше точности, но в зависимости от того, насколько точным вы должны быть, вы можете узнать достаточно о форматах файлов, просто открыв некоторые файлы изображений в двоичном редакторе, чтобы увидеть, как они структурированы. .

Эти ресурсы могут вам помочь:

0 голосов
/ 12 ноября 2018

Follow 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);
...