PHP:来自图像字节的图像 mime 类型

PHP: image mime type from image bytes

简介

我有一个从数据库中检索到的 base64 图像字符串:$imageBase64Str

我需要从此内容中检索 mime 并显示图像。这是以下代码的作用:

function imgMime($imgBytes){
    if(is_null($imgBytes)){
        return(false);
    }
    if(strlen($imgBytes)<12){
        return(false);
    }
    $file = tmpfile();
    if(!fwrite($file,$imgBytes,12)){
        fclose($file);
        return(false);
    }
    $path = stream_get_meta_data($file)['uri'];
    $mimeCode=exif_imagetype($path);
    fclose($file);
    if(!$mimeCode){
        return(false);
    }
    return(image_type_to_mime_type($mimeCode));
}

$imageBytes=base64_decode($imageBase64Str,true);
if(!$imageBytes){
    throw new Exception("cannot decode image base64");
}
$imageMime=imgMime($imageBytes);
if(!$imageMime){
    throw new Exception("cannot recognize image mime");
}
header('Content-type: '.$imageMime);
echo($imageBytes);

问题

这个解决方案的问题是它要求我将内容的前 12 个字节写入一个临时文件。我想知道是否有一种简单的方法可以避免这种情况而不必手动维护一组哑剧。另外,我想避免调用外部程序(例如通过 exec),以便我的代码保持可移植性。

理想情况下

我希望有一个像 exif_imagetype_from_bytes 这样的 php 函数。我的 imgMime 函数会更简单:

function imgMime($imgBytes){
    if(is_null($imgBytes)){
        return(false);
    }
    if(strlen($imgBytes)<12){
        return(false);
    }
    $mimeCode=exif_imagetype($imgBytes);
    if(!$mimeCode){
        return(false);
    }
    return(image_type_to_mime_type($mimeCode));
}

$imageBytes=base64_decode($imageBase64Str,true);
if(!$imageBytes){
    throw new Exception("cannot decode image base64");
}
$imageMime=imgMime($imageBytes);
if(!$imageMime){
    throw new Exception("cannot recognize image mime");
}
header('Content-type: '.$imageMime);
echo($imageBytes);

编辑:基于所选答案的解决方案

非常感谢@Kunal Raut 的回答,让我想出了以下解决方案:

function imgMime($imgBytes){
    if(is_null($imgBytes)){
        return(false);
    }
    if(strlen($imgBytes)<12){
        return(false);
    }
    $finfo = new finfo(FILEINFO_MIME_TYPE);
    $mime=$finfo->buffer($imgBytes);
    if(strncmp($mime, "image/", 6) != 0){
        return(false);
    }
    return($mime);
}

$imageBytes=base64_decode($imageBase64Str,true);
if(!$imageBytes){
    throw new Exception("cannot decode image base64");
}
$imageMime=imgMime($imageBytes);
if(!$imageMime){
    throw new Exception("cannot recognize image mime");
}
header('Content-type: '.$imageMime);
echo($imageBytes);

这个解决方案更优雅恕我直言。

The issue I have with this solution is that it requires me to write the 12 first bytes of the content to a temporary file. I am wondering whether there could be a simple way to avoid this without having to maintain a set of mimes manually.

这是因为你的这部分代码

if(!fwrite($file,$imgBytes,12)){
        fclose($file);
        return(false);
    }

它让你在文件中写入至少 12 个字节的数据,然后让执行移动 forward.You 可以跳过这个 if() 并解决你的第一个问题。

I wish there was a php function like exif_imagetype_from_bytes. My imgMime function would be simpler

是的,有这样的函数 returns 你是 base64_decoded 字符串的类型。

finfo_buffer()

有关此功能的更多详细信息Click Here

函数的使用

Check out this