Comment redimensionner et convertir une image téléchargée au format PNG à l'aide de GD ?

StackOverflow https://stackoverflow.com/questions/22259

  •  09-06-2019
  •  | 
  •  

Question

Je souhaite permettre aux utilisateurs de télécharger des images de type avatar dans une variété de formats (GIF, JPEG et PNG au moins), mais pour les sauvegarder tous sous BLOB de base de données PNG.Si les images sont surdimensionnées, au niveau des pixels, je souhaite les redimensionner avant l'insertion dans la base de données.

Quelle est la meilleure façon d'utiliser GD pour effectuer le redimensionnement et la conversion PNG ?

Modifier:Malheureusement, seulement DG est disponible sur le serveur que je dois utiliser, non ImageMagick.

Était-ce utile?

La solution

<?php                                              
/*
Resizes an image and converts it to PNG returning the PNG data as a string
*/
function imageToPng($srcFile, $maxSize = 100) {  
    list($width_orig, $height_orig, $type) = getimagesize($srcFile);        

    // Get the aspect ratio
    $ratio_orig = $width_orig / $height_orig;

    $width  = $maxSize; 
    $height = $maxSize;

    // resize to height (orig is portrait) 
    if ($ratio_orig < 1) {
        $width = $height * $ratio_orig;
    } 
    // resize to width (orig is landscape)
    else {
        $height = $width / $ratio_orig;
    }

    // Temporarily increase the memory limit to allow for larger images
    ini_set('memory_limit', '32M'); 

    switch ($type) 
    {
        case IMAGETYPE_GIF: 
            $image = imagecreatefromgif($srcFile); 
            break;   
        case IMAGETYPE_JPEG:  
            $image = imagecreatefromjpeg($srcFile); 
            break;   
        case IMAGETYPE_PNG:  
            $image = imagecreatefrompng($srcFile);
            break; 
        default:
            throw new Exception('Unrecognized image type ' . $type);
    }

    // create a new blank image
    $newImage = imagecreatetruecolor($width, $height);

    // Copy the old image to the new image
    imagecopyresampled($newImage, $image, 0, 0, 0, 0, $width, $height, $width_orig, $height_orig);

    // Output to a temp file
    $destFile = tempnam();
    imagepng($newImage, $destFile);  

    // Free memory                           
    imagedestroy($newImage);

    if ( is_file($destFile) ) {
        $f = fopen($destFile, 'rb');   
        $data = fread($f);       
        fclose($f);

        // Remove the tempfile
        unlink($destFile);    
        return $data;
    }

    throw new Exception('Image conversion failed.');
}

Autres conseils

Les étapes de votre processus devraient ressembler à ceci :

  1. Vérifier le Type de fichier
  2. Chargez l'image s'il s'agit d'un type de fichier pris en charge dans GD en utilisant imagecréerà partir de*
  3. Redimensionner en utilisant imagecopierredimensionner ou imagecopierééchantillonnée
  4. Enregistrez l'image en utilisant imagepng ($ handle, 'filename.png', $quality, $filters)

ImageMagick est plus rapide, génère de meilleures images, est plus configurable et est enfin (OMI) beaucoup plus facile à coder.

@ceejayoz Attendez juste le nouveau GD - c'est de la POO comme MySQLi et ce n'est en fait pas mal :)

Si vous souhaitez utiliser gdlib, utilisez gdlib 2 ou supérieur.Il a une fonction appelée imagecopyresampled(), qui interpolera les pixels lors du redimensionnement et aura une bien meilleure apparence.

De plus, j'ai toujours entendu dire sur le net que le stockage d'images dans la base de données est une mauvaise forme :

  • L'accès est plus lent que le disque
  • Votre serveur devra exécuter un script pour accéder à l'image au lieu de simplement servir un fichier
  • Votre script est désormais responsable de beaucoup de choses que le serveur Web a utilisées:
    • Définition de l'en-tête Content-Type approprié
    • Définition des en-têtes de mise en cache/délai d'attente/E-tag appropriés, afin que les clients puissent correctement mettre en cache l'image.Si vous ne le faites pas correctement, le script de service d'image sera exécuté à chaque requête, augmentant encore plus la charge sur le serveur.

Le seul avantage que je vois est que vous n’avez pas besoin de synchroniser votre base de données et vos fichiers image.Cependant, je le déconseillerais quand même.

Êtes-vous sûr de n'avoir pas ImageMagick sur le serveur ?

Je vous invite à utiliser PHP (la question est étiquetée avec PHP).La société d'hébergement que j'utilise n'a pas d'extension ImageMagick activée selon phpinfo().

Mais quand je leur ai posé des questions, ils ont répondu voici la liste des programmes ImageMagick disponibles à partir du code PHP.C'est très simple : il n'y a pas d'interface de messagerie instantanée en PHP, mais je peux appeler des programmes de messagerie instantanée directement depuis PHP.

J'espère que vous avez la même option.

Et moi fortement d'accord - stocker des images dans une base de données n'est pas une bonne idée.

Quelque chose comme ça, peut-être :


<?php
   //Input file
   $file = "myImage.png";
   $img = ImageCreateFromPNG($file);

   //Dimensions
   $width = imagesx($img);
   $height = imagesy($img);
   $max_width = 300;
   $max_height = 300;
   $percentage = 1;

   //Image scaling calculations
   if ( $width > $max_width ) { 
      $percentage = ($height / ($width / $max_width)) > $max_height ?
           $height / $max_height :
           $width / $max_width;
   }
   elseif ( $height > $max_height) {
      $percentage = ($width / ($height / $max_height)) > $max_width ? 
           $width / $max_width :
           $height / $max_height;
   }
   $new_width = $width / $percentage;
   $new_height = $height / $percentage;

   //scaled image
   $out = imagecreatetruecolor($new_width, $new_height);
   imagecopyresampled($out, $img, 0, 0, 0, 0, $new_width, $new_height, $width, $height);

   //output image
   imagepng($out);
?>

Je n'ai pas testé le code, il peut donc y avoir des erreurs de syntaxe, mais il devrait vous donner une présentation juste de la façon dont cela pourrait être réalisé.De plus, j'ai supposé un fichier PNG.Vous souhaiterez peut-être avoir une sorte d’instruction switch pour déterminer le type de fichier.

Cet article il semble que cela corresponde à ce que vous voulez.Vous devrez changer la fonction de sauvegarde imagejpeg() en imagepng() et lui faire enregistrer le fichier dans une chaîne plutôt que de le sortir sur la page, mais à part cela, il devrait être facile de copier/coller dans votre code existant.

La GD est-elle absolument nécessaire ? ImageMagick est plus rapide, génère de meilleures images, est plus configurable et est enfin (OMI) beaucoup plus facile à coder.

Je pense cette page est un bon point de départ.Il utilise imagecreatefrom(jpeg/gif/png), redimensionne et convertit l'image, puis la sort vers le navigateur.Au lieu de générer le navigateur, vous pouvez générer un BLOB dans une base de données sans plusieurs minutes de réécriture de code.

phpThumb est une abstraction de haut niveau qui mérite peut-être d'être examinée.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top