Введение
У меня есть строка изображения 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
), чтобы мой код оставался переносимым.
В идеале
I wi sh было php функция как exif_imagetype_from_bytes
. Моя функция 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);
Это решение намного элегантнее ИМХО.