PHP: тип пантомимы изображения из байтов изображения - PullRequest
0 голосов
/ 26 мая 2020

Введение

У меня есть строка изображения 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);

Это решение намного элегантнее ИМХО.

1 Ответ

1 голос
/ 26 мая 2020

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

Это из-за этой части вашего кода

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

Это заставляет вас записать минимум 12 байтов данных в файл, а затем позволяет продолжить выполнение. Вы можете пропустить это if() и решить вашу первую проблему.

I wi sh php функция как exif_imagetype_from_bytes. Моя функция imgMime была бы проще

Да, есть такая функция, которая возвращает вам тип строки base64_decoded .

finfo_buffer()

Для получения дополнительной информации об этой функции Щелкните здесь .

Использование функции

Проверьте это

...