简体   繁体   English

从 PHP 中的 base64 字符串检测图像类型

[英]Detecting image type from base64 string in PHP

Is it possible to find out the type of an image encoded as a base64 String in PHP?是否可以找出在 PHP 中编码为 base64 字符串的图像的类型?

I have no method of accessing the original image file, just the encoded string.我没有访问原始图像文件的方法,只能访问编码字符串。 From what I've seen, imagecreatefromstring() can create an image resource from a string representation (after it's been decoded from base64), but it automatically detects the image type and the image resource itself is a special PHP representation.据我imagecreatefromstring()imagecreatefromstring()可以从字符串表示(从 base64 解码后imagecreatefromstring()创建图像资源,但它会自动检测图像类型,并且图像资源本身是一种特殊的 PHP 表示。 In case I want to save the image as a file again, I would have no idea if the type I am saving it as corresponds to the original type from which the String representation was created.如果我想再次将图像另存为文件,我将不知道我保存的类型是否与创建字符串表示的原始类型相对应。

FileInfo can do that for you: FileInfo可以为您做到这一点:

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

$f = finfo_open();

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

If you dont want to use these functions because of their dependencies you can use the first bytes of the data:如果您不想使用这些函数,因为它们的依赖性,您可以使用数据的第一个字节:

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

The solution given by @Marc B is the best one for me (if our php version is > 5.3.0 otherwise we can use the solution given by @Aaron Murgatroyd). @Marc B 给出的解决方案对我来说是最好的(如果我们的 php 版本 > 5.3.0 否则我们可以使用 @Aaron Murgatroyd 给出的解决方案)。

I would like to give a little addition to this solution.我想对这个解决方案做一些补充。

To get the image type you can do it like this :要获取图像类型,您可以这样做:

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

In fact, (if you don't know it) the mime type for images is : image/type and type can be png or gif or jpeg or ...事实上,(如果你不知道的话)图像的 mime 类型是:图像/类型类型可以是 png 或 gif 或 jpeg 或 ...

Hope that can help someone and thanks to @Marc B for his solution.希望可以帮助某人并感谢@Marc B 的解决方案。

For an exhaustive list of mime type you can look here :有关 mime 类型的详尽列表,您可以在此处查看:

The way shown by @Marc B is the nicest. @Marc B 展示的方式是最好的。

Should FInfo not be available, the only other way I know is to store the data into a file, and run a getimagesize() on it.如果FInfo不可用,我知道的唯一另一种方法是将数据存储到文件中,并在其上运行getimagesize()

If you know a minimal amount about the file format structure, you could theoretically look at the top bytes of the file until you could work out what type of file it is.如果您对文件格式结构知之甚少,理论上您可以查看文件的顶部字节,直到您确定它是什么类型的文件。

For example, a GIF image always starts with the following bytes GIF89a .例如,GIF 图像始终以以下字节GIF89a开头。 If you can find that string at the begining of the file, you can be reasonably sure that it is a GIF image and absolutely certain it isn't any other image format.如果您能在文件的开头找到该字符串,您就可以合理地确定它是一个 GIF 图像,并且绝对确定它不是任何其他图像格式。 (it could still be a text file though, that just happens to start with 'GIF89a'; you'd have to parse more of the file to be absolutely certain) (不过,它仍然可能是一个文本文件,恰好以“GIF89a”开头;您必须解析更多文件才能绝对确定)

Likewise, PNG files have the string PNG fairly near the start (it's not quite at the very begining; again, you'd need to research the file format specifics to help you determine how much you'd need to know to be certain).同样,PNG 文件的字符串PNG相当接近开头(它不是一开始;同样,您需要研究文件格式细节以帮助您确定需要知道多少才能确定)。

JPEGs also contain recognisable strings in their headers, although these are more varied and complex. JPEG 还在其标头中包含可识别的字符串,尽管这些字符串更加多样和复杂。 You might want to look out for the string Exif .您可能需要注意字符串Exif

Getting the file format definitions would definitely give you more accuracy, but depending on how accurate you need to be, you might learn enough about the files formats just by opening some image files in a binary editor to see how they're structured.获取文件格式定义肯定会给您带来更高的准确性,但取决于您需要达到的准确程度,您只需在二进制编辑器中打开一些图像文件以查看它们的结构,就可以了解足够的文件格式。

These resources may help you:这些资源可以帮助您:

Follow PHP.NET Fileinfo :-按照PHP.NET 文件信息:-

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

Code below will get the image type from its mime type.下面的代码将从它的 mime 类型中获取图像类型。

<?php 
$base64 = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAKIAAAAxCAYAAABZAHL2AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAgfSURBVHhe7ZwxTBVLFIaH916wACstoDChEENhIxWYoJUmSqeJWkmiNkQS6TBBzSskUStNoNOCYCOJUKmJoVETY6WVjdJrow1UUvDyjfe/OYy7e+/ivbLknS/Z7N3ZndkzZ/45c3ZZ7RgeHt4MjrPD/FXbO86O4kJ0KoEL0akELkSnErgQnUrgQnQqQVuFODo6Go4dO1Y7cpx82ibEycnJMD09HW7cuBF6e3trpY6TTduEuLa2Fvfd3d3hzp078bfj5PH3gQMH/q39bikfPnwIg4ODMRru27cv7N27N7x796521nG20tKImOaDU1NTYX19Pf4+d+6c54tOLi2LiOSC4+PjoaenJ7x58yaW/fjxI3z8+DGcPn06Hg8NDYWVlZW6OB1HtCQisgQr2vGkPDs7G3NDeP/+fXj06FH87fmik0dLIuKXL19i/nfixInQ2dkZ80KiH9Hw+/fvni86DWlZjvj58+dw5syZuIf+/v4wNzcXBQieLzpFtPSpmZyQHJCohxCJjuSHX79+jdExzReXl5djnSpB1MZ2bHb+HNuOiOR7T58+DZcvX97ywpqod/v27XpeCLzYZtsN+SIThUi+m2G1IU9/+fJlePv2bSyjT/zWcdXYthB5KEGACBFBIjQrSAQ3MzNTX471EPPkyZOYMxJxHjx4EM+VhXZoz/kVRMgEJyXSA+NuYNtCRGB2+UIYEqTywmfPnoWrV6/WxUg5MxORXrx4sZ5PloV2eE3k/Mr58+drv0K4fv16mJiYqB1Vm20LEZHxcELUSwVJxGJDMOlDDFHz06dPdXE67eP169cxHdoNtOwfT7EkMBuPHDlSK/kJAmQ5xilXrlyJAm4UCRHwqVOn6ks91/OSXE4lz6Gd58+fx2POI2zyO+5PPcp4rcQ1qehpn+vYuObFixf1tkk12I4ePRqPBU/6HR0dsS8Wlj/1+9ChQ3GS0dfFxcV4/u7du6Grqyveh0krsJHVA1ZXV8P9+/e3tAWpbcDHJAcPHox1KKfP1KOP9NXWVz7OnpVI5WnfGvWBP1awAslOQZ2RkZHcciD9ajTe0PJ/xccgM5DqtMCpY2NjDSMhEZUBQng4BGiTJ1nq045NuHE+D0cMEGLhmGt4V6kndCKy7nvt2rXoKJxDJMfBtI3TcWaWELHn+PHjMc2wTmUA5+fnt+TGApGwLDKIsuPs2bPRNsAGbAEE+urVqygWbEmRbSBB0R/ub9GETH1PX/KESBt5983qw8mTJ+u+JBVT3205PqE9jilvhtJLM4ZjAAmxBGcdgvEMGE5XxAKiiQwt4tKlS1GEvHdkJrPRHmLSIALlOBQRAhESp+mJnYGjDhCJQVGbWYqouQd7hED9LPJECIhfA4HN3JcHMWDyMKmsD+y7U84LRIiNEgP20Rf9qZQJZq8HfM5E0j2xDRstnGMrAn/ovnl9IDoK2UEdOwHxEVCm9tROM5QWIqGbm+FUhMhs4jVBKk5EgygkSBu6i6BtKzjRSMQMhF3CgDqUyzE4Heeky2teulAkQpCwOKeJw14QRbBJObSiCiLS0oVvsBOxAW1gH/VoS4Opuhbs4nr2bKmPOMdWhNrFxrw+IES1LSEiUIt8YSeMFXAjSgtRg5qSipPlkxBNhFPO0QwMDJ1nYBB03v3yoI7dbLTmOBVrHogQZ9v6KTpnRcqApZFAwlcUUfQA/GL7SKqAD7Vtbv7MnKiXYidsKsJmUbtpW2kfdIwPQRNJ5RzjD50HIn2zFApRL0BtTobjWDZYPpg9GJIVLQAHM5gsYSKrTQuRk3tcuHAhChoxcy3CKBIF9yEyU8duZYUsaE9vBMiRisiK4KB720nIZFX0oG3Okc8K7muFqAhjB7gdFI0hqA8cY5MEzHgp4jPBZCe6KDM5/qntmwansymy2NCPcWwYg3MxmuMy7/wwXnmfYOAQ882bN7csG4J7IFSlANYBPLUWCTgP5Y30lVdRLOvpki40KCkSKHvyL6IG0T5LoII+qN6fJM9HsoXoho9BD1kIEAHTD1YwNvkiq29FbPs9YhYYjUARJ4Igb+GBIX1dUBY6hSi0HKRoYJVvWayDmaV5oknRwwv9oV2iU1pX97LRyi5P1hYbUYSErbcDQB38l7W1g2b7wF4PT+lEkq9s39ouRLu0ltmaheiXNTtxjJYAnGKXMznLOgI4tmXKP7U0CpbDtK5FD1qKBELORqB6ULN/P7eDwWDJTmBSKNpQrlwL+zThaJcopEj0O9h70w9shTJ9SPNrnSMqamyA47JRvaUR8XdBgCzBS0tLdaew8UROXqKogKBYBnAo5TiIgeSYZZSBY09+aUEM1KVt63SuR4x5MIjkxDa/AwSq3Ipy2lNOR7kihbCDih0WpRT4gHSCyUu/sYtN7W4Xm1aQZmArlOmDtR9brTDtOfu7WQo/A5OxIBHYsjJk1U+XGz4Jo+PMrj179oTDhw/HckRGzqaO81EtjuBVEh/e4jA6z+/9+/fHz9B423/v3r3A+0vK9SEu13E9EYD6Gxsb4fHjx2FhYSGe53pmsyKUoA735LwGzn72Rnt89obt3OPWrVvxegvt9vX1xWsePny45RM42Ui/1RZgB5NA9mMz9WgjFTPknbd9wi6dL9MHfnMNe+pYH3379q3eN0RPf8pQ+JcVu6T+bp4n2tGms/up1NLs/H9pOiK2A4+IjvCI6FQCF6JTCfw/c3cqgUdEpxK4EJ1K4EJ0KoEL0akELkSnErgQnUrgQnQqgQvRqQQuRKcSdPT39/tfVpwdp2NgYMCF6OwwIfwHN+rCnrjztp8AAAAASUVORK5CYII=";

$image_info = getimagesize($base64);

$extension = (isset($image_info["mime"]) ? explode('/', $image_info["mime"] )[1]: "");

echo $extension;
 
?>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM