Wie kann ich mit GD die Größe eines hochgeladenen Bildes ändern und es in ein PNG konvertieren?

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

  •  09-06-2019
  •  | 
  •  

Frage

Ich möchte Benutzern ermöglichen, Bilder im Avatar-Stil in verschiedenen Formaten hochzuladen (Zumindest GIF, JPEG und PNG), sondern um sie alle als zu speichern PNG-Datenbank-BLOBs.Wenn die Bilder pixelweise übergroß sind, möchte ich ihre Größe vor dem DB-Einfügen ändern.

Was ist der beste Weg, GD für die Größenänderung und PNG-Konvertierung zu verwenden?

Bearbeiten:Leider nur GD ist auf dem Server verfügbar, den ich verwenden muss, nein ImageMagick.

War es hilfreich?

Lösung

<?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.');
}

Andere Tipps

Ihre Prozessschritte sollten wie folgt aussehen:

  1. Verifizieren Die Dateityp
  2. Laden Sie das Bild mit in GD, wenn es sich um einen unterstützten Dateityp handelt Bilderstellenaus*
  3. Größenänderung mit Bildkopiegröße oder imagecopyresampled
  4. Speichern Sie das Bild mit imagepng($handle, 'filename.png', $quality, $filters)

ImageMagick ist schneller, generiert bessere Bilder, ist besser konfigurierbar und schließlich (meiner Meinung nach) viel einfacher zu programmieren.

@ceejayoz Warte einfach auf das neue GD – es ist OOP wie MySQLi und eigentlich nicht schlecht :)

Wenn Sie gdlib verwenden möchten, verwenden Sie gdlib 2 oder höher.Es verfügt über eine Funktion namens imagecopyresampled(), die Pixel bei der Größenänderung interpoliert und viel besser aussieht.

Außerdem habe ich im Internet immer gehört, dass das Speichern von Bildern in der Datenbank ein schlechter Ton ist:

  • Der Zugriff ist langsamer als auf die Festplatte
  • Ihr Server muss ein Skript ausführen, um zum Bild zu gelangen, anstatt einfach eine Datei zu bedienen
  • Ihr Skript ist jetzt für viele Dinge verantwortlich, die der Webserver verwendet hat:
    • Festlegen des richtigen Content-Type-Headers
    • Festlegen der richtigen Caching-/Timeout-/E-Tag-Header, damit Clients das Bild richtig zwischenspeichern können.Wenn Sie dies nicht richtig machen, wird das Image-Serving-Skript bei jeder Anfrage aufgerufen, was die Belastung des Servers noch weiter erhöht.

Der einzige Vorteil, den ich sehe, ist, dass Sie Ihre Datenbank und Bilddateien nicht synchronisieren müssen.Ich würde trotzdem davon abraten.

Sind Sie sicher, dass sich kein ImageMagick auf dem Server befindet?

Ich hoffe, Sie verwenden PHP (die Frage ist mit PHP getaggt).Das Hosting-Unternehmen, das ich nutze, hat laut phpinfo() keine ImageMagick-Erweiterung aktiviert.

Aber als ich sie danach fragte, sagten sie: Hier ist die Liste der ImageMagick-Programme, die über PHP-Code verfügbar sind.Ganz einfach: In PHP gibt es keine IM-Schnittstelle, aber ich kann IM-Programme direkt aus PHP aufrufen.

Ich hoffe, Sie haben die gleiche Option.

Und ich stark Ich stimme zu – das Speichern von Bildern in einer Datenbank ist keine gute Idee.

Etwas in der Art, vielleicht:


<?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);
?>

Ich habe den Code nicht getestet, daher kann es zu Syntaxfehlern kommen, aber er sollte Ihnen eine faire Vorstellung davon geben, wie das gemacht werden könnte.Außerdem bin ich von einer PNG-Datei ausgegangen.Möglicherweise möchten Sie eine Art Switch-Anweisung verwenden, um den Dateityp zu bestimmen.

Dieser Artikel Scheint, als würde es zu dem passen, was Sie wollen.Sie müssen die Funktion zum Speichern von imagejpeg() in imagepng() ändern und dafür sorgen, dass die Datei in einer Zeichenfolge gespeichert wird, anstatt sie auf der Seite auszugeben. Ansonsten sollte es jedoch einfach sein, sie in Ihren vorhandenen Code zu kopieren und einzufügen.

Ist GD unbedingt erforderlich? ImageMagick ist schneller, erzeugt bessere Bilder, ist besser konfigurierbar und schließlich (meiner Meinung nach) viel einfacher zu programmieren.

Ich finde diese Seite ist ein guter Ausgangspunkt.Es verwendet imagecreatefrom(jpeg/gif/png) und ändert die Größe, konvertiert das Bild und gibt es dann an den Browser aus.Anstatt den Browser auszugeben, könnten Sie ohne viele Minuten Code-Umschreiben in ein BLOB in einer Datenbank ausgeben.

phpThumb ist eine Abstraktion auf hoher Ebene, die einen Blick wert sein könnte.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top