2008-08-22 11 views
9

Desidero consentire agli utenti di caricare immagini di tipo avatar in una varietà di formati (GIF, JPEG e PNG almeno), ma per salvarli tutti come PNG database BLOB. Se le immagini sono sovradimensionate, in pixel, voglio ridimensionarle prima dell'inserimento del DB.Come ridimensionare e convertire un'immagine caricata in un PNG usando GD?

Qual è il modo migliore per utilizzare GD per eseguire il ridimensionamento e la conversione PNG?

Modifica: Purtroppo, solo il GD è disponibile sul server che è necessario utilizzare, non ImageMagick.

+0

Non servire o memorizzare immagini da o sul DB. – dlamblin

risposta

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

Grazie per questa soluzione! :) Funziona anche con foto parzialmente trasparenti (era il mio problema originale)! – bastiandoeen

0

This article sembra che si adatterebbe quello che vuoi. Avrai bisogno di cambiare la funzione di salvataggio imagejpeg() in imagepng() e far sì che salvi il file in una stringa invece di inviarlo alla pagina, ma a parte questo dovrebbe essere facile copiare/incollare nel tuo codice esistente.

0

GD è assolutamente necessario? ImageMagick è più veloce, genera immagini migliori, è più configurabile e, infine, è (IMO) molto più facile da codificare.

+0

Sembra una semplice pubblicità. Qualche prova? – Green

+0

Sicuro. Per creare una miniatura ritagliata: '$ image = new Imagick ($ image_path); $ image-> cropThumbnailImage (100,100); 'Prova a farlo in GD in due righe di codice. ImageMagick è un toolkit progettato specificamente per manipolare le immagini, quindi in genere sarà meglio di una parte di PHP generata in modo casuale. – ceejayoz

0

Penso che this page sia un buon punto di partenza. Usa imagecreatefrom (jpeg/gif/png) e ridimensiona e converte l'immagine e quindi restituisce al browser. Invece di emettere il browser, è possibile eseguire l'output su un BLOB in un DB senza molti minuti di riscrittura del codice.

3

Se si desidera utilizzare gdlib, utilizzare gdlib 2 o versione successiva. Ha una funzione chiamata imagecopyresampled(), che interpola i pixel durante il ridimensionamento e ha un aspetto molto migliore.

Inoltre, ho sempre sentito notato giro per la rete che la memorizzazione delle immagini nel database è cattiva forma:

  • E 'più lento per l'accesso a quella del disco
  • Il server sarà necessario eseguire uno script per raggiungere l'immagine al posto di semplicemente servire un file
  • lo script ora è responsabile di un sacco di roba il server web utilizzato per gestire :
    • Se intestazione corretta Content-Type
    • Impostazione delle intestazioni di caching/timeout/E-tag corrette, in modo che i client possano memorizzare correttamente l'immagine nella cache. Se non lo fai correttamente, lo script di pubblicazione delle immagini verrà colpito ad ogni richiesta, aumentando ulteriormente il carico sul server.

L'unico vantaggio che posso vedere è che non è necessario per mantenere i file di database e di immagine sincronizzato. Lo raccomanderei comunque contro di esso.

+0

Sicuramente fa schifo per servire le immagini da un DB rispetto a scaricarle sul proprio server statico light-wieght su un dominio statico o su un cdn. – dlamblin

6

I suoi passi di processo dovrebbe essere simile a questo:

  1. Verify il filetype
  2. caricare l'immagine, se si tratta di un tipo di file supportato nella GD usando imagecreatefrom*
  3. ridimensionamento utilizzando imagecopyresize o imagecopyresampled
  4. Salvare il immagine utilizzando imagepng($handle, 'filename.png', $quality, $filters)

ImageMagick è più veloce, genera immagini migliori, è più configurabile e, infine, è (IMO) molto più facile da codificare.

@ceejayoz Basta aspettare per il nuovo GD - è OOP come MySQLi e in realtà non è male :)

3

Sei sicuro di non avere ImageMagick sul server?

I guest si utilizza PHP (la domanda viene contrassegnata con PHP). La società di hosting che uso non ha un'estensione ImageMagick attivata secondo phpinfo().

Ma quando ho chiesto loro hanno detto ecco l'elenco dei programmi ImageMagick disponibili dal codice PHP. Semplicemente - non ci sono interfacce IM in PHP, ma posso chiamare programmi IM direttamente da PHP.

Spero che tu abbia la stessa opzione.

E I fortemente acconsento - la memorizzazione di immagini nel database non è una buona idea.

3

Qualcosa di simile, forse:


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

non ho ancora testato il codice in modo ci potrebbero essere alcuni errori di sintassi, ma dovrebbe dare una presentazione attendibile su come potrebbe essere fatto. Inoltre, ho assunto un file PNG. Potresti voler avere qualche tipo di istruzione switch per determinare il tipo di file.

0

phpThumb è un'astrazione di alto livello che può valere la pena guardare.