[PHP] Upload immagini e ridimensionamento automatico

  • Creatore Discussione Creatore Discussione _LAIL_
  • Data di inizio Data di inizio

_LAIL_

Utente Attivo
19 Set 2013
57
0
6
Salve a tutti ancora una volta ho bisogno della vostra grandissima esperienza e bravura


girando per la rete ho trovato una classe ottima che ridimensiona le foto e funziona benissimo.

Il problema per la quale chiedo il vostro aiuto e che il ridimensionamento lo fa mantenendo le proporzioni, e a me serve che deve ridimensionare nelle dimensioni che gli do io, inoltre non gestisce le trasparenze.

questo e lo script di caricamento:

PHP:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Ridimensionare immagini con SmartImage</title>
</head>

<body>
<form action="carica.php" method="post" enctype="multipart/form-data">
	<input type="file" name="foto" class="input">
	<br />
	<br />
	<input type="submit" name="invia" value="Carica immagine" />
</form>


<?php
include "SmartImage.class.php";
$file = $_FILES["foto"];
if($file["name"] != ""){
    if($file["error"] == 0){
        $img = new SmartImage($file["tmp_name"]);
        $img->resize(600, 300); // dimensioni massime immagine
		$img->saveImage("slideshow/" . $file["name"]); // salvo l'immagine dove voglio e come voglio
    
		echo "Immagine Caricata con successo";
		
	}else{
        echo "Errore!!!!!!";
    }
} 
 
?>
<p>
<img src="slideshow/<?php echo $file['name'];?>" /><br>
    <font size="3" color="#000000"><br><?php echo $file["name"];?><br></font>
	
</p>
</body>
</html>




Questa e la classe:

PHP:
<?php

/**
 * Smart, easy and simple Image Manipulation
 * 
 * @author Alessandro Coscia, Milano, Italy, [email protected]
 * http://www.codicefacile.it/smartimage
 * @copyright LGPL
 * @version 0.9.6
 *
 */
class SmartImage {
	/**
	 * Source file (path)
	 */
	private $src;

	/**
	 * GD image's identifier
	 */
	private $gdID;

	/**
	 * Image info
	 */
	private $info;

	/**
	 * Initialize image
	 *
	 * @param string $src
   * @param boolean $big
	 * @return SmartImage
	 */
	public function SmartImage($src, $bigImageSize=false) {
    // In case of very big images (more than 1Mb)
    if ($bigImageSize)
      $this->setMemoryForBigImage($src);
    
	// set data
	$this->src = $src;
	$this->info = getimagesize($src);
	
    // open file
	if ( $this->info[2] == 2 )		$this->gdID = imagecreatefromjpeg($this->src);
	elseif ( $this->info[2] == 1 )	$this->gdID = imagecreatefromgif($this->src);
	elseif ( $this->info[2] == 3 ) 	$this->gdID = imagecreatefrompng($this->src);
	
	}
  
  /**
   * Set memory in case of very big images (more than 1Mb)
   * new SmartImage($src, true) to activate this function
   * Works with (PHP 4 >= 4.3.2, PHP 5) if compiled with --enable-memory-limit
   *   or PHP>=5.2.1
   * Thanks to Andrvm and to Bascunan for this feature
   */
	private function setMemoryForBigImage($filename) {
    $imageInfo    = getimagesize($filename);
	  $memoryNeeded = round(($imageInfo[0] * $imageInfo[1] * $imageInfo['bits'] * $imageInfo['channels'] / 8 + Pow(2, 16)) * 1.65);
	   
	  $memoryLimit = (int) ini_get('memory_limit')*1048576;
	
	  if ((memory_get_usage() + $memoryNeeded) > $memoryLimit) {
		 ini_set('memory_limit', ceil((memory_get_usage() + $memoryNeeded + $memoryLimit)/1048576).'M');
		 return (true);
    }
	  else return(false);
	}

	/**
	 * Resize an image
	 *
	 * @param integer $w
	 * @param integer $h
	 * @param boolean $cutImage
	 * @return boolean Everything is ok?
	 */
	public function resize($width, $height, $cutImage = false) {
		if ($cutImage)
		return $this->resizeWithCut($width, $height);
		else
		return $this->resizeNormal($width, $height);
	}

	/**
	 * Resize an image without cutting it, only do resize
	 * saving proportions and adapt it to the smaller dimension
	 *
	 * @param integer $w
	 * @param integer $h
	 */
	private function resizeNormal($w, $h) {
		// set data
		$size = $this->info;
		$im = $this->gdID;
		$newwidth = $size[0];
		$newheight = $size[1];

		if( $newwidth > $w ){
			$newheight = ($w / $newwidth) * $newheight;
			$newwidth = $w;
		}
		if( $newheight > $h ){
			$newwidth = ($h / $newheight) * $newwidth;
			$newheight = $h;
		}

		$new = imagecreatetruecolor($newwidth, $newheight);
		$result = imagecopyresampled($new, $im, 0, 0, 0, 0, $newwidth, $newheight, $size[0], $size[1]);

		@imagedestroy($im);
		$this->gdID = $new;
		$this->updateInfo();

		return $result;
	}

	/**
	 * Resize an image cutting it, do resize
	 * adapt it resizing and cutting the original image
	 *
	 * @param integer $w
	 * @param integer $h
	 */
	private function resizeWithCut($w, $h){
		// set data
		$size = $this->info;
		$im = $this->gdID;

		if( $size[0]>$w or $size[1]>$h ){
			$centerX = $size[0]/2;
			$centerY = $size[1]/2;

			$propX = $w / $size[0];
			$propY = $h / $size[1];

			if( $propX < $propY ){
				$src_x = $centerX - ($w*(1/$propY)/2);
				$src_y = 0;
				$src_w = ceil($w * 1/$propY);
				$src_h = $size[1];
			}
			else {
				$src_x = 0;
				$src_y = $centerY - ($h*(1/$propX)/2);
				$src_w = $size[0];
				$src_h = ceil($h * 1/$propX);
			}

			// Resize
      $new = imagecreatetruecolor($w, $h);
			$result = imagecopyresampled($new, $im, 0, 0, $src_x, $src_y, $w, $h, $src_w, $src_h);
			
			@imagedestroy($im);
		}
		else{
			$new = $im;
		}

		$this->gdID = $new;
		$this->updateInfo();

		return $result;
	}
	
	/**
	 * Add a Water Mark to the image
	 * (filigrana)
	 *
	 * @param string $from
	 * @param string $waterMark
	 */
	public function addWaterMarkImage($waterMark, $opacity = 35, $x = 5, $y = 5){
		// set data
		$size = $this->info;
		$im = $this->gdID;

		// set WaterMark's data	
		$waterMarkSM = new SmartImage($waterMark);
		$imWM = $waterMarkSM->getGDid();
	
		// Add it!
		// In png watermark images we ignore the opacity (you have to set it in the watermark image)
		if ($waterMarkSM->info[2] == 3)
			imageCopy($im, $imWM, $x, $y, 0, 0, imagesx($imWM), imagesy($imWM));
		else
			imageCopyMerge($im, $imWM, $x, $y, 0, 0, imagesx($imWM), imagesy($imWM), $opacity);
		$waterMarkSM->close();
	
		$this->gdID = $im;
	}
  
	/**
	 * Rotate of $degrees
	 *
	 * @param integer $degrees
	 */  
  public function rotate($degrees=180) {
    $this->gdID = imagerotate($this->gdID, $degrees, 0);
    $this->updateInfo();
  }

	/**
	 * Show Image
	 *
	 * @param integer 0-100 $jpegQuality
	 */
	public function printImage($jpegQuality = 100) {
		$this->outPutImage('', $jpegQuality);
	}

	/**
	 * Save the image on filesystem
	 *
	 * @param string $destination
	 * @param integer 0-100 $jpegQuality
	 */
	public function saveImage($destination, $jpegQuality = 100) {
		$this->outPutImage($destination, $jpegQuality);
	}

	/**
	 * Output an image
	 * accessible throught printImage() and saveImage()
	 *
	 * @param unknown_type $dest
	 * @param unknown_type $jpegQuality
	 */
	private function outPutImage($dest = '', $jpegQuality = 100) {
		$size = $this->info;
		$im = $this->gdID;
		// select mime
		if (!empty($dest))
			list($size['mime'], $size[2]) = $this->findMime($dest);
		
		// if output set headers
		if (empty($dest))	header('Content-Type: ' . $size['mime']);
		
		// output image
		if( $size[2] == 2 )			imagejpeg($im, $dest, $jpegQuality);
		elseif ( $size[2] == 1 )	imagegif($im, $dest);
		elseif ( $size[2] == 3 )	imagepng($im, $dest);
	}

	/**
	 * Mime type for a file
	 *
	 * @param string $file
	 * @return string
	 */
	private function findMime($file) {
		$file .= ".";
		$bit = explode(".", $file);
		$ext = $bit[count($bit)-2];
		if ($ext == 'jpg')		return array('image/jpeg', 2);
		elseif ($ext == 'jpeg')	return array('image/jpeg', 2);
		elseif ($ext == 'gif')	return array('image/gif', 1);
		elseif ($ext == 'png')	return array('image/png', 3);
		else return array('image/jpeg', 2);
	}

	/**
	 * Get the GD identifier
	 *
	 * @return GD Identifier
	 */
	public function getGDid() {
		return $this->gdID;
	}
  
	/**
	 * Get actual Image Size
	 *
	 * @return array('x' = integer, 'y' = integer)
	 */
	public function getSize() {
    $size = $this->info;
		return array('x' => $size[0], 'y' => $size[1]);
	}
	
	/**
	 * Set GD identifier
	 *
	 * @param GD Identifier $value
	 */
	public function setGDid($value) {
		$this->gdID = $value;
	}

	/**
	 * Free memory
	 */
	public function close() {
		@imagedestroy($this->gdID);
	}
	
	/**
	 * Update info class's variable
	 */
	private function updateInfo() {
		$info = $this->info;
		$im = $this->gdID;
		
		$info[0] = imagesx($im);
		$info[1] = imagesy($im);
		
		$this->info = $info;
	}
  
}

?>
 
Ciao, se impsti le dimensioni esatte e l'ultimo parametro a true nella funzione resize() la classe penserà a ritagliare l'immagine qualora fosse più grande
PHP:
$img->resize(600, 400, true); // dimensioni massime immagine
 
Salve, anche io utilizzo questa classe per ridimensionare le immagini, però se io imposto un valore fisso alcune foto vengono ritagliate male, sapete dirmi se a questa classe esiste una funzione per scalare automaticamente le immagini mantenendo le proporzioni originali? A me serve solo scalare la foto in modo da ridurre il peso.
 
Ciao, nel tuo caso non serve passare il terzo parametro
 
PHP:
$img->resize(600, 400);
i due parametri indicano la larghezza e l'altezza massima che dovrà avere l'immaginie una volta ridimensionata
 
Ciao, lo so che quel paramentro imposta le dimensioni, e se non passo questo parametro l'immagine viene caricata con le dimensioni di peso reali. A me interessa ridimensionare immagini molto grandi ma in percentuale automatica, nel senso se una foto pesa 5mb ed è grande 2100x2100 px vorrei che si scalasse in proporzione in modo da essere più piccola e piu leggera. Se imposto le dimensioni fisse andranno bene per immagini proporzionate, ma ovviamente ci sono alcune con dimensioni strane tipo 450 x 650 px e non riesco a ridimensionarle correttamente.
 
Ciao a tutti,
Allora io ho questo problema,
Utilizzo SmartImage e tutto funziona perfettamente, peccato che funziona solo da PC, mi spiego meglio:
Io sul mio sito tramite PC carico una o diverse foto e tramite SmartImage le uploado in due cartelle, nella cartella gallery metto le foto con dimensioni originali che prelevo dalla funzione list($width,$height) mentre in gallery/mosaico/ faccio uploadare la stessa foto con dimensioni ovviamente più piccole in maniera da ottenere una risoluzione da Thumbnails.
Il tutto funziona perfettamente se carico le foto che ho sul pc via browser PC, ma se provo a caricare le foto con il cellulare, quindi prendendole dalla libreria ecco che non ne viene caricata nemmeno una.
Come è possibile? Non conosco bene i limiti di SmartImage, non credo però possa trattarsi di un problema di risoluzione perchè la stessa foto che ho sul mio iPhone cel'ho anche sul PC e se la carico col computer viene caricata ed anche ridimensionata.
Quale potrebbe essere il problema?
Ora vi posto il codice quì di seguito:

PHP:
require_once("smartimage.class.php");
if(ISSET($_POST['carica'])) {
if($_POST['secureCode']!==$_POST['norobot']) {
echo "<h1>Errore caricamento</h1>
La somma inserita non è corretta.<br />
Torna in Photoalbum e riprova inserendo però la cifra esatta.<br />
";
} else {
for($f=0; $f<count($_FILES['foto']); $f++) {
if(file_exists("gallery/".$_FILES['foto']['name'][$f])) {
$foto_name="_".$_FILES['foto']['name'][$f];
} else {
$foto_name=$_FILES['foto']['name'][$f];
}
list($width,$height,$type,$attr)=getimagesize($_FILES['foto']['tmp_name'][$f]);
$thumb=new SmartImage($_FILES['foto']['tmp_name'][$f]);
$thumb->resize($width,$height,true);
$thumb->saveImage("gallery/$foto_name",100);
$thumb->resize(128,128,true,true);
$thumb->saveImage("gallery/mosaico/$foto_name",85);
}
echo "<h1>Conferma caricamento foto</h1>Il caricamento della foto si è concluso con successo.<br />La foto è stata aggiunta con successo al Photoalbum.<br /><br />Grazie per lo scatto; per aggiungere un'altra foto o per vedere il Photoalbum con la foto appena aggiunta vai nuovamente in Photoalbum.<br />";
}
} else {
header("location: index.php");
}

Fatemi sapere se si tratta di un problema nel codice oppure no.

Aggiungo: ovviamente nel campo input di tipo file come name ho messo foto[] le parentisi quadre servono per creare un array in maniera da permettere un upload multiplo di file.
Stesso problema preciso che me lo dava anche senza parentisi quadre quindi con upload singolo.

Grazie mille a tutti in anticipo per le risposte che spero saranno utili
 
Ultima modifica di un moderatore:
Però ora mi è venuta un'idea:
Faccio sempre i controlli sulla risoluzione e nel caso la condizione sia vera quindi height<width quindi immagine ruotata faccio applicare la rotazione a smartimage di 90 gradi così me la riposiziona giusta.
Ora provo!!!

Ti faccio sapere grazie.
 
ciao
penso che il tuo ragionamento abbia un errore di fondo, se fai due foto una con l'apparecchio verticale e una con l'apparecchio orizzontale quando le carichi così come sono vengono caricate entrambe con lo stesso orientamento per cui height non sarà mai maggiore di width (o viceversa).
quindi non ti serve w e h per conoscere la rotazione con cui è stata ripresa un'immagine, avevo trovato una funzione php per farlo ma non riesco a farla funzionare.
credo che l'unica sia avvisare l'utente di caricare le immagini col loro giusto orientamento, a quel punto si che ti conviene scampbiare w con h
PHP:
<?php
//.....
list($width,$height,$type,$attr)=getimagesize($_FILES['foto']['tmp_name'][$f]);
$thumb=new SmartImage($_FILES['foto']['tmp_name'][$f]);
if($height > $width){//inverto i valori
    $swap=$width;
    $width=$height;
    $height=$swap;
}
$thumb->resize($width,$height,true);
//.....
?>
 

Discussioni simili