Подтвердить что ты не робот

Обнаружение типа изображения из строки base64 в PHP

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

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

4b9b3361

Ответ 1

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

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

$f = finfo_open();

$mime_type = finfo_buffer($f, $imgdata, FILEINFO_MIME_TYPE);

Ответ 2

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

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

Ответ 3

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

Я хотел бы дать небольшое дополнение к этому решению.

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

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

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

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

Для исчерпывающего списка типа mime вы можете посмотреть здесь:

Ответ 4

Самый показательный способ, показанный @Marc B.

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

Ответ 5

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

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

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

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

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

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