Getimagesize súper rápido en php

Estoy tratando de obtener el tamaño de la imagen (dimensiones, ancho y alto de la imagen) de cientos de imágenes remotas y getimagesize es demasiado lento.

Leí un poco y descubrí que la forma más rápida sería usar file_get_contents para leer una cierta cantidad de bytes de las imágenes y examinar el tamaño dentro de los datos binarios.

¿Alguien intentó esto antes? ¿Cómo examinaría los diferentes formatos? ¿Alguien ha visto alguna biblioteca para esto?

preguntado el 08 de enero de 11 a las 20:01

Probablemente sea lento porque las imágenes son remoto. Descárgalos primero y getimagesize() será increíblemente rápido. Después de todo, solo lee ciertos bytes binarios de las imágenes. -

por eso quiero usar file_get_contents para 1) No descargar el archivo completo. 2) leer solo ciertos bytes para obtener el tamaño de la imagen -

en realidad, utilizo fopen y fgets para leer solo esos bytes binarios -

¿Los sitios remotos no dan una Content-Length ¿encabezamiento? -

Me sorprendería que getimagesize () descargara mucho más del archivo de lo necesario. -

3 Respuestas

function ranger($url){
    $headers = array(
    "Range: bytes=0-32768"
    );

    $curl = curl_init($url);
    curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
    $data = curl_exec($curl);
    curl_close($curl);
    return $data;
}

$start = microtime(true);

$url = "http://news.softpedia.com/images/news2/Debian-Turns-15-2.jpeg";

$raw = ranger($url);
$im = imagecreatefromstring($raw);

$width = imagesx($im);
$height = imagesy($im);

$stop = round(microtime(true) - $start, 5);

echo $width." x ".$height." ({$stop}s)";

prueba ...

640 x 480 (0.20859 s)

La carga de 32 kb de datos funcionó para mí.

Respondido 24 Abr '12, 00:04

solo lea este artículo y explica los diferentes y mejores métodos para recuperar el archivo php-mysql-tutorial.com/wikis/php-tutorial/… . Paso 2. Cómo diferenciar los diferentes códigos binarios extraídos para obtener el tamaño de la imagen - Sir Lojik

No confiaría en el tutorial de php escrito en aspx: PI actualizó mi respuesta, debería tener todo lo que necesita. Si no es así, lo siento, no entiendo del todo tu pregunta. Si desea compararlo en binario, tendrá que cargarlo por completo en una cadena. - Dejan Marjanović

@webarto Creo que quiere las dimensiones de la imagen, que estarán en los metadatos de la imagen, no en los metadatos del archivo. Tendrá que descargar los bytes iniciales del archivo, pero cuántos dependen del formato de imagen. - Moinudin

Por cierto, debería haberlo especificado, estoy buscando las dimensiones de la imagen. déjame editar - Sir Lojik

Con el parámetro de rango tuve problemas con archivos PNG más grandes. La mejor manera en mi caso es mejorar la API no solo para obtener la URL de la imagen, sino también el tamaño u orientación. - poseer

He creado una biblioteca PHP para exactamente este escenario, funciona descargando el mínimo absoluto del archivo remoto necesario para determinar el. Esto es diferente para cada imagen y particularmente para JPEG depende de cuántas miniaturas incrustadas haya en el archivo.

Está disponible en GitHub aquí: https://github.com/tommoor/fastimage

Ejemplo de uso:

$image = new FastImage($uri);
list($width, $height) = $image->getSize();
echo "dimensions: " . $width . "x" . $height;

Respondido el 26 de Septiembre de 12 a las 16:09

Esto funciona para mí más lento que getimagesize de PHP: Imagen rápida: 0.079681873321533s Tamaño nativo de getimage: 0.023485898971558s Raeger (ejemplo de webarto): 0.16773s - catalinux

Me interesaría mucho si es reproducible más lento, ¿cuántas veces realizaste la prueba? Puede consultar el código fuente; normalmente se necesita menos de 1 kb de la imagen para descargarla. - tom

Realmente me gusta esta clase. sin embargo estás usando fopen. por lo que tardará mucho tiempo en ralentizar la solicitud remota de respuesta con el servidor de sobrecarga. ¿Por qué no usas CURL en su lugar? Y algunos sitios web necesitan un encabezado falso (http_referer) para recuperar las dimensiones de la imagen. Entonces CURL es mejor. - TomSawyer

¿Qué pasa si quiero el en bytes? - codigo vaquero

@codecowboy Use () para una solicitud local o HTTP HEAD y un encabezado de longitud de contenido para remoto - TheJosh

Estaba buscando una mejor manera de manejar esta situación, así que utilicé algunas funciones diferentes que se encuentran en Internet.

En general, cuando funcionó, el más rápido tendió a ser el getjpegsize función que James Relyea publicó en la página PHP para getimagesize, superando el ranger función proporcionada por Dejan arriba. http://php.net/manual/en/function.getimagesize.php#88793

Image #1 (787KB JPG on external older server)
getimagesize: 0.47042 to 0.47627 - 1700x2340 [SLOWEST]
getjpegsize: 0.11988 to 0.14854 - 1700x2340 [FASTEST]
ranger: 0.1917 to 0.22869 - 1700x2340

Image #2 (3MB PNG)
getimagesize: 0.01436 to 0.01451 - 1508x1780 [FASTEST]
getjpegsize: - failed
ranger: - failed

Image #3 (2.7MB JPG)
getimagesize: 0.00855 to 0.04806 - 3264x2448 [FASTEST]
getjpegsize: - failed
ranger: 0.06222 to 0.06297 - 3264x2448 * [SLOWEST]

Image #4 (1MB JPG)
getimagesize: 0.00245 to 0.00261 - 2031x1434
getjpegsize: 0.00135 to 0.00142 - 2031x1434 [FASTEST]
ranger: 0.0168 to 0.01702 - 2031x1434 [SLOWEST]

Image #5 (316KB JPG)
getimagesize: 0.00152 to 0.00162 - 1280x720
getjpegsize: 0.00092 to 0.00106 - 1280x720 [FASTEST]
ranger: 0.00651 to 0.00674 - 1280x720 [SLOWEST]
  • ranger falló al tomar 32768 bytes en la imagen n. ° 3, así que lo aumenté a 65536 y funcionó para tomar el tamaño con éxito.

Sin embargo, hay problemas, ya que ambos ranger y getjpegsize están limitadas de manera que no lo hacen lo suficientemente estable para su uso. Ambos fallaron al tratar con una imagen JPG grande de alrededor de 3 MB, pero ranger funcionará después de cambiar la cantidad de bytes que captura. Además, estas alternativas solo tratan con imágenes JPG, lo que significa que se necesitaría usar un condicional para usarlas solo en JPG y getimagesize en los otros formatos de imagen.

Además, tenga en cuenta que la primera imagen estaba en un servidor más antiguo que ejecutaba una versión antigua de PHP 5.3.2, mientras que las otras 4 imágenes provenían de un servidor moderno (cPanel basado en la nube con MultiPHP marcado de nuevo a 5.4.45 para compatibilidad).

Vale la pena señalar que el servidor basado en la nube funcionó mucho mejor con getimagesize que venció ranger, de hecho, para las 4 pruebas en el servidor en la nube, ranger fue el más lento. Esos 4 también extraían las imágenes del mismo servidor en el que se estaba ejecutando el código, aunque con diferentes cuentas.

Esto me hace preguntarme si el núcleo de PHP mejoró en 5.4 o si la versión de Apache tiene en cuenta. Además, podría depender de la disponibilidad del servidor y la carga del servidor. No olvidemos cómo las redes son cada vez más rápidas cada año, por lo que tal vez el problema de la velocidad se esté volviendo menos preocupante.

Entonces, el resultado final y mi respuesta es que para un soporte completo para todos los formatos de imagen web, y para lograr un tamaño de imagen súper rápido, podría ser mejor absorberlo y usar getimagesize y luego almacenar en caché los tamaños de las imágenes (si estas imágenes se verificarán más de una vez) en una tabla de base de datos. En ese escenario, solo la primera verificación tendrá un costo mayor, pero las solicitudes posteriores serían mínimas y más rápidas que cualquier función que lea los encabezados de la imagen.

Al igual que con cualquier almacenamiento en caché, solo funciona bien si el contenido no cambia y hay una manera de verificar si ha habido un cambio. Por lo tanto, una posible solución es verificar solo los encabezados de la URL de una imagen al verificar el caché y, si es diferente, volcar la versión en caché y volver a tomarla con getimagesize.

respondido 10 mar '17, 02:03

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.