2008-08-22 6 views
9

Ich möchte Benutzern erlauben, avatar-artige Bilder in einer Vielzahl von Formaten (GIF, JPEG und PNG mindestens) hochzuladen, aber sie alle als PNG Datenbank BLOBs zu speichern. Wenn die Bilder pixelweise übergroß sind, möchte ich sie vor dem DB-Einfügen skalieren.Wie ändere ich die Größe und konvertiere ein hochgeladenes Bild mit GD in ein PNG?

Was ist der beste Weg, GD zu verwenden, um die Größe neu bestimmen und die PNG-Konvertierung zu tun?

Bearbeiten: Traurig, nur ist auf dem Server, den ich brauche, keine ImageMagick.

+0

Stellen Sie keine Bilder von der DB bereit oder speichern Sie sie nicht. – dlamblin

Antwort

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

Danke für diese Lösung! :) Es funktioniert sogar mit teilweise transparenten Bildern (das war mein ursprüngliches Problem)! – bastiandoeen

0

This article scheint, wie es passen würde, was Sie wollen. Sie müssen die Funktion imagejpeg() in imagepng() speichern und die Datei in einer Zeichenfolge speichern, anstatt sie auf der Seite auszugeben. Ansonsten sollte sie jedoch einfach in Ihren vorhandenen Code kopiert und eingefügt werden.

0

Ist GD unbedingt erforderlich? ImageMagick ist schneller, erzeugt bessere Bilder, ist konfigurierbarer und ist schließlich (IMO) viel einfacher zu codieren.

+0

Klingt aber ein einfacher Werbespot. Irgendwelche Beweise? – Green

+0

Sicher. Um ein zugeschnittenes Thumbnail zu machen: '$ image = new Imagick ($ image_path); $ image-> cropThumbnailImage (100,100); 'Versuchen Sie das in GD in zwei Zeilen Code. ImageMagick ist ein Toolkit, das speziell für die Manipulation von Bildern entwickelt wurde. Es ist also im Allgemeinen besser als ein zufälliger Teil von PHP. – ceejayoz

0

Ich denke, this page ist ein guter Ausgangspunkt. Es verwendet imagecreatefrom (jpeg/gif/png) und ändert die Größe und konvertiert das Bild und gibt es dann an den Browser aus. Anstatt den Browser auszugeben, könnten Sie in einem DB ein BLOB ausgeben, ohne viel Code neu schreiben zu müssen.

3

Wenn Sie verwenden gdlib möchten, verwenden Sie gdlib 2 oder höher. Es hat eine Funktion namens imagecopyresampled(), die Pixel bei der Größenanpassung interpoliert und viel besser aussieht.

Außerdem habe ich immer um das Netz hörte darauf hingewiesen, dass die Bilder in der Datenbank schlechte Form zu speichern:

  • Es ist langsamer Zugang als die Scheibe
  • Ihr Server muss ein Skript ausführen zu erhalten auf das Bild, anstatt einfach eine Datei dient
  • jetzt Ihr Skript für eine Menge Sachen verantwortlich ist der Web-Server verwendet zu handhaben:
    • Se tting den richtigen Content-Type-Header
    • den richtigen Caching/timeout/E-Tag-Header einstellen, damit Kunden das Bild richtig cachen. Wenn dies nicht richtig gemacht wird, wird das Image-Serving-Script bei jeder Anfrage getroffen, was die Serverlast noch mehr erhöht.

Der einzige Vorteil, den ich sehen kann, ist, dass Sie Ihre Datenbank und Bild keine Dateien synchronisiert halten müssen. Ich würde es trotzdem empfehlen.

+0

Es ist definitiv suck, um Bilder aus einer DB zu liefern, im Vergleich dazu, sie auf ihren eigenen statischen statischen Server in einer statischen Domäne oder einer CDN auszulagern. – dlamblin

6

Ihre Prozessschritte sollte wie folgt aussehen:

  1. Verify die die filetype
  2. Legen Sie das Bild, wenn es ein unterstütztes Dateityp in GD ist mit imagecreatefrom*
  3. Ändern der Größe mit imagecopyresize oder imagecopyresampled
  4. speichern Bild mit imagepng($handle, 'filename.png', $quality, $filters)

ImageMagick ist schneller, erzeugt bessere Bilder, ist konfigurierbarer und schließlich (IMO) viel einfacher zu codieren.

@ceejayoz wartet nur für die neuen GD - es ist OOP wie MySQLi und es ist eigentlich nicht schlecht :)

3

Sind Sie sicher, dass Sie keinen ImageMagick auf dem Server haben?

Ich Gast Sie PHP verwenden (Frage ist mit PHP getaggt). Hosting-Firma, die ich verwende, hat keine ImageMagick-Erweiterung aktiviert nach phpinfo().

Aber wenn ich fragte sie über sie sagte hier ist die Liste der ImageMagick-Programme von PHP-Code. So einfach - es gibt keine IM-Schnittstelle in PHP, aber ich kann IM-Programme direkt von PHP aus aufrufen.

Ich hoffe, Sie haben die gleiche Option.

Und ich stark zustimmen - Bilder in der Datenbank speichern ist keine gute Idee. vielleicht

3

Etwas Ähnliches,:


<?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, so könnte es einige Syntaxfehler sein, aber es sollte Ihnen eine wahrheitsgetreue Darstellung, wie es getan werden könnte. Außerdem nahm ich eine PNG-Datei an. Sie könnten eine Art switch-Anweisung haben, um den Dateityp zu bestimmen.

0

phpThumb ist eine High-Level-Abstraktion, die auf der Suche wert sein können.

Verwandte Themen