toba_ef_editable_captcha - Obtener imagen tipo MIME de recursos en PHP/GD?
php_gd2 (4)
Estoy tratando de encontrar el tipo de mimo de una imagen. PHP tiene la función getimagesize
pero solo toma un nombre de archivo, mientras que en cambio tengo un "recurso" de imagen, es decir, una imagen creada a partir de imagecreatefromstring
.
Encontré las funciones imagesx
e imagesy
que devuelven el ancho / alto de un recurso pero no puedo encontrar ninguna función que me diga el tipo mime de un recurso. ¿Alguien sabe de una forma de hacer esto?
Nota: Debido a una configuración de servidor extraña, no podemos leer / escribir archivos desde el servidor normalmente, solo a través de una capa FTP (que es de donde leí los datos de imagen).
Podrías usar las funciones PHP fileinfo.
$image_buffer = SomeFunctionToGetStringBufferFromGD();
$fileinfo = finfo_open();
$type = finfo_buffer($fileinfo, $image_buffer);
Utiliza los números mágicos (lo mismo que el comando de archivo Unix) para identificar el tipo de archivo.
Sé que esto es bastante viejo, pero solo en caso de que alguien se encuentre con esta publicación como yo lo hice ...
Una mejor opción ha sido lanzada desde PHP 5.4.0: getimagesizefromstring
Esta nueva función es exactamente igual a getimagesize, pero le permite recuperar la información de una secuencia.
Si tiene acceso a los datos binarios de la imagen (como sugiere el uso de imagecreatefromstring ()), puede detectar el tipo de archivo "manualmente":
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];
}
Abusar de un contenedor de secuencias se vuelve un poco más complicado. Al menos si no queremos jugar con variables globales.
// 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);
Una imagen creada con imagecreatefromstring
ya no tiene ningún tipo MIME, se decodifica desde su formato original y se almacena en el formato interno de GD.
La misma pregunta fue hecha hace un tiempo con el mismo resultado.
El único camino a seguir es capturar la imagen antes de que se imagecreatefromstring
imagen imagecreatefromstring
, y de alguna manera capturar la información de tamaño de la misma.
Usted dice que no puede hacer operaciones de lectura / escritura de archivos en su sistema, por lo que simplemente escribir el archivo está descartado.
El hecho de que getimagesize () no puede leer de las variables es conocido y lamentado: http://bugs.php.net/bug.php?id=44239
El chico menciona una solución novedosa : registrar un nuevo contenedor de flujo que permita operaciones de archivo en variables .
¿Es esta una opción en la configuración de tu servidor?