PHP: image mime type from image bytes

牧云@^-^@ 提交于 2020-06-01 05:07:01

问题


Introduction

I have a base64 image string retrieved from a database: $imageBase64Str

I need to retrieve the mime from this content and display the image. This is what the following code does:

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

Question

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. Also, I would like to avoid calling an external program (through exec for example) so that my code remains portable.

Ideally

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

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

Edit: Solution based on selected answer

Thanks a lot to @Kunal Raut for the answer that allowed me to come up with the following solution:

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

This solution is a lot more elegant IMHO.


回答1:


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.

This is because of this part of your code

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

It makes you write minimum 12 bytes of data in the file and then lets the execution move forward.You can skip this if() and solve your first problem.

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

Yes there is such function which returns you the type of the base64_decoded string.

finfo_buffer()

For more details regarding this function Click Here.

Use of function

Check out this



来源:https://stackoverflow.com/questions/62028464/php-image-mime-type-from-image-bytes

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!