2011-09-17 5 views
11

Estoy buscando obtener las dimensiones, el ancho y la altura de un archivo JPG alojado remotamente. He visto cómo es posible hacer esto descargando la imagen completa.¿Cómo determinar el tamaño de una imagen sin descargarla (en su totalidad)?

Sin embargo, sería ideal si pudiera hacerlo descargando solo lo suficiente para obtener esta información.

imágenes típicas son 200 K en el tamaño y la lectura en sólo unos pocos K fuerza al principio podría ser suficiente para archivos JPG:

curl_setopt($ch, CURLOPT_RANGE, "0-4096");

Como referencia, he seguido estas respuestas/comentarios, pero en vano (aunque podrían estar en el camino correcto):

¿Alguien ha sido capaz de juntar las piezas (sin o con ImageMagick)?

+0

Lo han intentado? ¿Cuál es su comprensión del formato de archivo JPEG? Vea lo que puede armar desde http: //en.wikipedia.org/wiki/Exchangeable_image_file_format # Ejemplo – tripleee

+0

Intenté leer en los primeros 4096 bytes y no pude encontrar para ejecutar Imagemagick 'identify' o 'grep -n $ \ xc0' contra él (ver preguntas/comentarios referenciados). – donohoe

Respuesta

3

Pude responder mi propia pregunta y he incluido el fragmento de código PHP.

El único inconveniente (al menos para mí) es que esto escribe la descarga de imágenes parciales en el sistema de archivos antes de leer en las dimensiones con getImageSize.

Para mí bytes es el límite seguro para buscar imágenes jpg de 200 a 400 KB de tamaño.

function remoteImage($url){ 
    $ch = curl_init ($url); 
    curl_setopt($ch, CURLOPT_HEADER, 0); 
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); 
    curl_setopt($ch, CURLOPT_BINARYTRANSFER,1); 
    curl_setopt($ch, CURLOPT_RANGE, "0-10240"); 

    $fn = "partial.jpg"; 
    $raw = curl_exec($ch); 
    $result = array(); 

    if(file_exists($fn)){ 
     unlink($fn); 
    } 

    if ($raw !== false) { 

     $status = curl_getinfo($ch, CURLINFO_HTTP_CODE); 

     if ($status == 200 || $status == 206) { 

      $result["w"] = 0; 
      $result["h"] = 0; 

      $fp = fopen($fn, 'x'); 
      fwrite($fp, $raw); 
      fclose($fp); 

      $size = getImageSize($fn); 

      if ($size===false) { 
      // Cannot get file size information 
      } else { 
      // Return width and height 
       list($result["w"], $result["h"]) = $size; 
      } 

     } 
    } 

    curl_close ($ch); 
    return $result; 
} 
+0

Excelente solución, funciona para mí. gracias – ahoo

4

De acuerdo con Getting Image size of JPEG from its binary, el tamaño de la imagen no se almacena en una ubicación precisa en el archivo. Dependiendo de la extensión, puede tener un montón de datos en el archivo antes del tamaño real, por ejemplo, un correo de pulgar.

El siguiente código C++ debe ser un buen comienzo para su propia implementación de PHP: http://www.64lines.com/jpeg-width-height. Puede adaptar fácilmente este código accediendo a la cadena que contiene sus datos como una matriz: myString{$i} en lugar de data[i]

Debe cargar un fragmento relativamente grande de datos y analizarlo, luego cargar más si es necesario. O puede cargar el archivo bloque por bloque, pero la sobrecarga causada por las numerosas conexiones frustra el propósito de no cargar todo el archivo.

De todos modos, no estoy seguro de que los beneficios justifiquen el tiempo que pasa en esto. 200k no es nada hoy en día.

+0

Comprobaré, pero podría ser demasiado para mí. 200K no es mucho, es cierto, pero llegaría a ser aproximadamente 500 + mb por día, aunque mi enfoque actual es descargarlos todos en su totalidad. – donohoe

2

Una versión mejorada de la respuesta de donohoe anterior. Éste recupera rangos de bytes más pequeños para los archivos png y gif como se describe en here.

function remoteImage($url){ 

    $filename = parse_url($url); 
    $pi = pathinfo($filename['path'],PATHINFO_EXTENSION); 

    switch ($pi) { 
    case "jpg" : 
     $range = "0-15000"; 
     break; 
    case "jpeg" : 
     $range = "0-10000"; 
     break; 
    case "png": 
     $range = "0-100"; 
     break; 
    case "gif": 
     $range = "0-10"; 
     break; 
    default: 
     $range = "0-15000"; 
     break; 
    } 

    $ch = curl_init ($url); 
    curl_setopt($ch, CURLOPT_HEADER, 0); 
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); 
    curl_setopt($ch, CURLOPT_BINARYTRANSFER,1); 
    curl_setopt($ch, CURLOPT_RANGE, $range); 

    $fn = "partial2.png"; 
    $raw = curl_exec($ch); 
    $result = array(); 

    if(file_exists($fn)){ 
     unlink($fn); 
    } 

    if ($raw !== false) { 

     $status = curl_getinfo($ch, CURLINFO_HTTP_CODE); 

     if ($status == 200 || $status == 206) { 

      $result["w"] = 0; 
      $result["h"] = 0; 

      $fp = fopen($fn, 'x'); 
      fwrite($fp, $raw); 
      fclose($fp); 

      $size = getImageSize($fn); 

      if ($size===false) { 
       // Cannot get file size information 
      } else { 
       // Return width and height 
       list($result["w"], $result["h"]) = $size; 

      } 

     } 
    } 

    curl_close ($ch); 
    return $result; 
} 
6

¿Cómo sobre el uso de la funcionalidad de ImageMagick ping así:

identify -ping -format "%wx%h" http://www.google.com/logos/giroux1.jpg 
482x142 
+0

¡Guau, nunca supe sobre '-ping'! Las pruebas muestran que es solo un poco más rápido, pero guarda el paso de descargar un archivo temporal. – bigjosh

Cuestiones relacionadas