2011-09-17 8 views
11

Sto cercando di ottenere le dimensioni, la larghezza e l'altezza di un JPG ospitato in remoto. Ho visto come è possibile farlo scaricando l'immagine completa.Come determinare la dimensione di un'immagine senza scaricarla (per intero)?

Tuttavia, sarebbe ideale se potessi farlo scaricando solo quanto basta per ottenere questa informazione.

immagini tipiche sono 200K di dimensione e la lettura in pochi K forza all'inizio potrebbe essere sufficiente per JPG:

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

Per avere un riferimento, ho seguito queste risposte/commenti, ma senza alcun risultato (anche se potrebbe essere sulla strada giusta):

Qualcuno è riuscito a mettere insieme i pezzi (con o senza ImageMagick)?

+0

Che cosa hai provato? Qual è la tua comprensione del formato di file JPEG? Guarda cosa puoi mettere insieme da http: //en.wikipedia.org/wiki/Exchangeable_image_file_format # Esempio – tripleee

+0

Ho provato a leggere nei primi 4096 byte e non sono riuscito a trovare il modo per eseguire Imagemagick 'identifica' o 'grep -n $ \ xc0' contro di esso (vedi domande/commenti di riferimento). – donohoe

risposta

3

Sono riuscito a rispondere alla mia domanda e ho incluso lo snippet di codice PHP.

L'unico svantaggio (almeno per me) è che questo scrive il download parziale dell'immagine nel file system prima di leggere nelle dimensioni con getImageSize.

Per me byte è il limite sicuro per verificare la presenza di immagini jpg di dimensioni comprese tra 200 e 400 K.

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

Ottima soluzione, funziona per me. grazie – ahoo

4

Secondo Getting Image size of JPEG from its binary, la dimensione dell'immagine non è memorizzata in una posizione precisa nel file. A seconda dell'estensione, è possibile avere un intero gruppo di dati nel file prima della dimensione effettiva, ad esempio una thumbmail.

Il seguente codice C++ dovrebbe essere un buon inizio per la propria implementazione PHP: http://www.64lines.com/jpeg-width-height. È possibile adattare facilmente questo codice accedendo alla stringa contenente i dati come un array: myString{$i} anziché data[i]

È necessario caricare un blocco relativamente grande di dati e analizzarlo, quindi caricarne altri se necessario. Oppure puoi caricare il file blocco per blocco, ma il sovraccarico causato dalle numerose connessioni vanifica lo scopo di non caricare l'intero file.

In ogni caso, non sono sicuro che i vantaggi giustificheranno il tempo che trascorrerai su questo. 200k non è niente al giorno d'oggi.

+0

Controllerò, ma potrebbe essere troppo per me. 200K non è molto, è vero, ma potrebbe arrivare fino a 500 + Mb al giorno, anche se il mio attuale approccio per scaricarli completamente. – donohoe

2

Una versione migliorata della risposta di donohoe sopra. Questo recupera intervalli di byte più piccoli per i file png e gif come descritto 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

ne dite di usare la funzionalità di ImageMagick ping come questo:

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

Wow, non sapevo nemmeno di '-ping'! Il test mostra che è solo leggermente più veloce, ma salva il passaggio del download di un file temporaneo. – bigjosh

Problemi correlati