2010-10-23 6 views
2

J'aimerais pouvoir détecter les jpeg progressifs en utilisant python et les convertir en non progressifs.Comment détecter et convertir des jpeg progressifs avec python

(j'écris un outil pour gérer les images pour Android et jpegs progressifs semblent briser.)

+0

Ceci est un problème assez important. Il serait beaucoup plus facile d'utiliser un outil disponible sur le marché tel que Photoshop (ou peinture) pour automatiser la conversion. Avec Photoshop, cela prend cinq minutes. – JoshD

+1

Vous ne spécifiez pas votre plate-forme, mais essayez d'utiliser [jpegtran] (http://jpegclub.org/). – tzot

+0

Bon point - Je vise une plateforme croisée. L'outil fonctionne sous Windows en ce moment, mais fera probablement partie d'un service web sur django sous linux (où je ne pense pas que photoshop serait adapté ou facile à intégrer avec un petit script python). Je vais essayer jpegtran quand j'ai l'occasion de regarder @ ce prochain. –

Répondre

2

J'excuse à l'avance pour fournir une réponse à base de php, alors que la question a été posée au sujet de python. Néanmoins, je pense que cela ajoute de la valeur et peut être utile. Avant d'essayer de convertir une image progressive en une image non progressive, il est bon d'avoir une méthode de détection pour le Jpeg progressif.

Voici la fonction php qui le fait, pourrait facilement être réécrite dans d'autres langues (python serait un candidat), car il lit les données binaires et des marqueurs Jpeg (et donc ne comptez pas sur le langage bibliothèque spécifique)

public function checkProgressiveJPEG($filepath) { 
    $result = false; 
    // $this->log = 'started analysis...'; 

    // http://en.wikipedia.org/wiki/Jpeg 
    // for more details on JPEG structure 

    // SOI [0xFF, 0xD8] = Start Of Image 
    // SOF0 [0xFF, 0xC0] = Start Of Frame (Baseline DCT) 
    // SOF2 [0xFF, 0xC2] = Start Of Frame (Progressive DCT) 
    // SOS [0xFF, 0xDA] = Start Of Scan 

    if(file_exists($filepath)) { 
     $fs = @fopen($filepath, "rb"); 

     $bytecount = 0; 
     $byte_last = 0; 
     $buffer = 0; 
     $buffer_length = 4*1024; 
     $begins_with_SOI = false; 

     while($buffer = fread($fs, $buffer_length)) { 

      // always carry over previous ending byte 
      // just in case the buffer is read after a 0xFF marker 
      if($byte_last) { 
       $buffer = $byte_last.$buffer; 
      } 
      $byte_last = 0; 
      preg_match("/\.$/", $buffer, $matches); 
      if(count($matches)) { 
       $byte_last = $matches[0]; 
      } 

      // check if it begins with SOI marker 
      if(!$begins_with_SOI) { 
       preg_match("/^\\xff\\xd8/", $buffer, $matches); 
       if(count($matches)) { 
        $begins_with_SOI = true; 
       } else { 
        // $this->log = 'does not start with SOI marker'; 
        $result = false; 
        break; 
       } 
      } 

      // check if SOS or SOF2 is reached 
      preg_match("/\\xff(\\xda|\\xc2)/", $buffer, $matches); 
      if(count($matches)) { 
       if(bin2hex($matches[0]) == 'ffda') { 
        // $this->log = 'SOS is reached and SOF2 has not been detected, so image is not progressive.'; 
        $result = false; 
        break; 
       } else if(bin2hex($matches[0]) == 'ffc2') { 
        // $this->log = 'SOF2 is reached, so image is progressive.'; 
        $result = true; 
        break; 
       } 

      } 
     } // end while 

     fclose($fs); 
    } // end if 
    return $result; 
} 
+0

Beau travail, à la fin jpegtran était la chose la plus facile à intégrer avec mon script python. - Ce code semble très utile si quelqu'un veut faire une chose similaire dans une application web PHP. –

Questions connexes