Я пытаюсь найти тип пантомимы изображения. PHP имеет функцию getimagesize
но это только берет имя файла, тогда как у меня есть изображение "ресурс" вместо этого - т.е. изображение, созданное из imagecreatefromstring
.
Я нашел функции imagesx
и imagesy
которые возвращают ширину/высоту из ресурса, но я не могу найти функцию, которые говорят мне тип пантомимы от ресурса. Кто-либо знает о способе сделать это?
Примечание: Из-за странного настроенного сервера, мы не можем файлы чтения-записи с сервера обычно, только через уровень FTP (который является, где я считал данные изображения из).
Вы могли бы использовать функции PHP fileinfo.
$image_buffer = SomeFunctionToGetStringBufferFromGD();
$fileinfo = finfo_open();
$type = finfo_buffer($fileinfo, $image_buffer);
Он использует магические числа (такие же, как команда файла unix) для определения типа файла.
Образ, созданный с использованием imagecreatefromstring
, больше не имеет типа MIME, он декодируется из своего собственного формата и сохраняется во внутреннем формате GD.
Тот же вопрос был задан некоторое время назад с тем же результатом.
Единственный способ сделать это - поймать изображение до того, как оно получит imagecreatefromstring
, и каким-то образом уловить из него информацию о размере.
Вы говорите, что не можете выполнять операции чтения / записи файлов в своей системе, поэтому просто о записи файла не может быть и речи.
Тот факт, что getimagesize () не может читать из переменных, известен и причитается: http://bugs.php.net/bug.php?id=44239
Парень там упоминает изящный обходной путь : Регистрация новой оболочки потока, которая разрешает файловые операции с переменными .
Это опция в настройках вашего сервера?
Если у вас есть доступ к двоичным данным изображения (например, использование imagecreatefromstring ( ) предлагает), вы можете определить тип файла «вручную»:
function image_file_type_from_binary($binary) {
if (
!preg_match(
'/\A(?:(\xff\xd8\xff)|(GIF8[79]a)|(\x89PNG\x0d\x0a)|(BM)|(\x49\x49(?:\x2a\x00|\x00\x4a))|(FORM.{4}ILBM))/',
$binary, $hits
)
) {
return 'application/octet-stream';
}
static $type = array (
1 => 'image/jpeg',
2 => 'image/gif',
3 => 'image/png',
4 => 'image/x-windows-bmp',
5 => 'image/tiff',
6 => 'image/x-ilbm',
);
return $type[count($hits) - 1];
}
Злоупотребление оболочкой потока становится немного сложнее. По крайней мере, если мы не хотим возиться с глобальными переменными.
// getimagesize() from string
class GisFromString {
const proto_default = 'gisfromstring';
protected static $proto = null;
protected static $imgdata = null;
static function getImageSize($imgdata) {
if (null === self::$proto) {
self::register();
}
self::$imgdata = $imgdata;
// note: @ suppresses "Read error!" notices if $imgdata isn't valid
return @getimagesize(self::$proto . '://');
}
static function getMimeType($imgdata) {
return is_array($gis = self::getImageSize($imgdata))
? $gis['mime']
: $gis;
}
// streamwrapper helper:
const unregister = null;
// register|unregister wrapper for the given protocol|scheme
// return registered protocol or null
static function register(
$proto = self::proto_default // protocol or scheme
) {
if (self::unregister === $proto) { // unregister if possible
if (null === self::$proto) {
return null;
}
if (!stream_wrapper_unregister(self::$proto)) {
return null;
}
$return = self::$proto;
self::$proto = null;
return $return;
}
if (!preg_match('/\A([a-zA-Z][a-zA-Z0-9.+\-]*)(:([\/\x5c]{0,3}))?/', $proto, $h)) {
throw new Exception(
sprintf('could not register invalid scheme or protocol name "%s" as streamwrapper', $proto)
);
}
if (!stream_wrapper_register($proto = $h[1], __CLASS__)) {
throw new Exception(
sprintf('protocol "%s" already registered as streamwrapper', $proto)
);
}
return self::$proto = $proto;
}
// streamwrapper API:
function stream_open($path, $mode) {
$this->str = (string) self::$imgdata;
$this->fsize = strlen($this->str);
$this->fpos = 0;
return true;
}
function stream_close() {
self::$imgdata = null;
}
function stream_read($num_bytes) {
if (!is_numeric($num_bytes) || $num_bytes < 1) {
return false;
}
/* uncomment this if needed
if ($this->fpos + $num_bytes > 65540 * 4) {
// prevent getimagesize() from scanning the whole file
// 65_540 is the maximum possible bytesize of a JPEG segment
return false;
}
*/
if ($this->fpos + $num_bytes > $this->fsize) {
$num_bytes = $this->fsize - $this->fpos;
}
$read = substr($this->str, $this->fpos, $num_bytes);
$this->fpos += strlen($read);
return $read;
}
function stream_eof() {
return $this->fpos >= $this->fsize;
}
function stream_tell() {
return $this->fpos;
}
function stream_seek($off, $whence = SEEK_SET) {
if (SEEK_CUR === $whence) {
$off = $this->fpos + $off;
}
elseif (SEEK_END === $whence) {
$off = $this->fsize + $off;
}
if ($off < 0 || $off > $this->fsize) {
return false;
}
$this->fpos = $off;
return true;
}
}
// usage:
//$imgdata = file_get_contents('path/lenna.jpg');
// if the default protocol is already registered
//GisFromString::register('other');
var_dump(GisFromString::getImageSize($imgdata));
echo GisFromString::getMimeType($imgdata);