PHP: modifica della qualità dell'image quando la condizione è soddisfatta?

Ho uno script php in cui l'utente può caricare immagini. Voglio che lo script riduca la qualità dell'image (jpeg) se la dimensione del file è maggiore di 'X' kbyte.

Qualcosa come questo:

if( $_FILES['uploaded_img']['size'] > $file_size_limit ){ // code that lowers the quality of the uploaded image but keeps the image width and height } 

Qual è l'approccio migliore per questo?

ps: non voglio cambiare la width e l'altezza dell'image.

Certo che puoi. Fai qualcosa del genere.

 $upload = $_FILES['uploaded_img']; $uploadPath = 'new/path/for/upload/'; $uploadName = pathinfo($upload['name'], PATHINFO_FILENAME); $restrainedQuality = 75; //0 = lowest, 100 = highest. ~75 = default $sizeLimit = 2000; if($upload['size'] > $sizeLimit) { //open a stream for the uploaded image $streamHandle = @fopen($upload['tmp_name'], 'r'); //create a image resource from the contents of the uploaded image $resource = imagecreatefromstring(stream_get_contents($streamHandle)); if(!$resource) die('Something wrong with the upload!'); //close our file stream @fclose($streamHandle); //move the uploaded file with a lesser quality imagejpeg($resource, $uploadPath . $uploadName . '.jpg', $restrainedQuality); //delete the temporary upload @unlink($upload['tmp_name']); } else { //the file size is less than the limit, just move the temp file into its appropriate directory move_uploaded_file($upload['tmp_name'], $uploadPath . $upload['name']); } 

Questo accetterà qualsiasi formato di image supportto da PHP GD (supponendo che sia installato sul tuo server. Molto probabilmente lo è). Se l'image è inferiore al limite, caricherà l'image originale sul path specificato.

Il tuo approccio di base (che è implementato nella risposta di Austin) functionrà un po 'di tempo, ma è importnte tenere presente che qualità! = Dimensione del file . Sebbene siano generalmente correlati, è perfettamente ansible (anche comune) che la riduzione della qualità di un file jpeg possa effettivamente portre a un file PIÙ GRANDE. Questo perché qualsiasi JPEG caricato sul tuo sistema è già stato eseguito attraverso la formula di compressione JPEG (spesso con una qualità di 79 o 80). A seconda dell'image originale, questo process creerà artefatti / altererà l'image risultante. Quando esegui questa image già ottimizzata tramite l'algorithm di compressione jpeg una seconda volta non "sa" come fosse l'image originale … quindi tratta il jpeg in arrivo come se fosse un nuovo file lossless e prova a copiarlo il più vicino ansible … compresi eventuali artefatti creati nel process originale. Accoppiando questo con il fatto che la compressione jpeg originale ha già sfruttato la maggior parte dei trucchi di compressione "facili", finisce per essere piuttosto probabile che la compressione di una seconda volta si traduca in un'image dall'aspetto più schifoso (copia di un problema di copia) ma non più piccola file.

Ho fatto alcuni test per vedere where fosse il cutoff, e non sorprende che se l'image originale avesse un rapporto di compressione basso (q = 99) si fosse risparmiato molto spazio comprimendo nuovamente q = 75. Se l'originale è stato compresso a q = 75 (piuttosto comune per i valori predefiniti del programma grafico), la compressione secondaria q = 75 sembrava peggiorata, ma aveva praticamente le stesse size del file dell'originale. Se l'originale aveva un livello di compressione più basso (q = 50), la compressione secondaria q = 75 ha dato come risultato un file molto più grande (per questi test ho usato tre foto complesse … ovviamente le immagini con palati / composizioni specifici avranno performance diverse andando attraverso queste compressioni). Nota: sto utilizzando Fireworks CS4 per questo test … Mi rendo conto che questi indicatori di qualità non hanno standardizzazione tra le piattaforms

Come indicato nei commenti seguenti, lo spostamento da formati di file come PNG a JPEG di solito si riduce notevolmente (sebbene senza alcuna trasparenza), ma da JPEG -> JPEG (o GIF-> JPEG, specialmente per immagini semplici o di piccolo formato) spesso non aiuterà.

Indipendentemente da ciò, puoi ancora provare a utilizzare il metodo di compressione descritto da Austin, ma assicurati di confrontare le size dei file delle due immagini quando hai finito. Se c'è solo un piccolo guadagno incrementale o il nuovo file è più grande, ripristinare di nuovo l'image originale.