PHP
Elaborazione di immagini con GD
Ricerca…
Osservazioni
Quando si utilizza l' header("Content-Type: $mimeType");
e image____
per generare solo un'immagine nell'output, assicurati di non emettere nient'altro, nota anche una riga vuota dopo ?>
. (Questo può essere un "bug" difficile da rintracciare - non si ottiene alcuna immagine e nessun indizio sul perché.) Il consiglio generale è di non includere?> Affatto qui.
Creare un'immagine
Per creare un'immagine vuota, usa la funzione imagecreatetruecolor
:
$img = imagecreatetruecolor($width, $height);
$img
ora è una variabile di risorsa per una risorsa immagine con $width
x $height
pixel. Notare che la larghezza conta da sinistra a destra e l'altezza conta dall'alto verso il basso.
Le risorse di immagine possono anche essere create dalle funzioni di creazione dell'immagine , come ad esempio:
-
imagecreatefrompng
-
imagecreatefromjpeg
- altre
imagecreatefrom*
funzioniimagecreatefrom*
.
Le risorse di immagine possono essere liberate in seguito quando non ci sono più riferimenti a loro. Tuttavia, per liberare immediatamente la memoria (questo può essere importante se si elaborano molte immagini di grandi dimensioni), l'uso di imagedestroy()
su un'immagine quando non è più utilizzato potrebbe essere una buona pratica.
imagedestroy($image);
Convertire un'immagine
Le immagini create dalla conversione dell'immagine non modificano l'immagine finché non la si stampa. Pertanto, un convertitore di immagini può essere semplice come tre linee di codice:
function convertJpegToPng(string $filename, string $outputFile) {
$im = imagecreatefromjpeg($filename);
imagepng($im, $outputFile);
imagedestroy($im);
}
Uscita dell'immagine
Un'immagine può essere creata usando le funzioni image*
, dove *
è il formato del file.
Hanno questa sintassi in comune:
bool image___(resource $im [, mixed $to [ other parameters]] )
Salvataggio in un file
Se si desidera salvare l'immagine in un file, è possibile passare il nome file o un flusso di file aperto, come $to
. Se passi uno stream, non è necessario chiuderlo perché GD lo chiuderà automaticamente.
Ad esempio, per salvare un file PNG:
imagepng($image, "/path/to/target/file.png");
$stream = fopen("phar://path/to/target.phar/file.png", "wb");
imagepng($image2, $stream);
// Don't fclose($stream)
Quando usi fopen
, assicurati di usare il flag b
invece del flag t
, perché il file è un output binario.
Non cercare di passare fopen("php://temp", $f)
o fopen("php://memory", $f)
ad esso. Poiché lo stream viene chiuso dalla funzione dopo la chiamata, non potrai più utilizzarlo, ad esempio per recuperarne il contenuto.
Uscita come risposta HTTP
Se si desidera restituire direttamente questa immagine come risposta dell'immagine (ad esempio per creare badge dinamici), non è necessario passare nulla (o passare null
) come secondo argomento. Tuttavia, nella risposta HTTP, è necessario specificare il tipo di contenuto:
header("Content-Type: $mimeType");
$mimeType
è il tipo MIME del formato che si sta restituendo. Gli esempi includono image/png
, image/gif
e image/jpeg
.
Scrivere in una variabile
Ci sono due modi per scrivere in una variabile.
Utilizzo dell'OB (Output Buffering)
ob_start();
imagepng($image, null, $quality); // pass null to supposedly write to stdout
$binary = ob_get_clean();
Utilizzo dei wrapper di flusso
Potresti avere molte ragioni per cui non vuoi utilizzare il buffering dell'output. Ad esempio, potresti già avere OB. Pertanto, è necessaria un'alternativa.
Utilizzando la funzione stream_wrapper_register
, è possibile registrare un nuovo wrapper stream. Quindi, è possibile passare un flusso alla funzione di output dell'immagine e recuperarla in seguito.
<?php
class GlobalStream{
private $var;
public function stream_open(string $path){
$this->var =& $GLOBALS[parse_url($path)["host"]];
return true;
}
public function stream_write(string $data){
$this->var .= $data;
return strlen($data);
}
}
stream_wrapper_register("global", GlobalStream::class);
$image = imagecreatetruecolor(100, 100);
imagefill($image, 0, 0, imagecolorallocate($image, 0, 0, 0));
$stream = fopen("global://myImage", "");
imagepng($image, $stream);
echo base64_encode($myImage);
In questo esempio, la classe GlobalStream
scrive qualsiasi input nella variabile di riferimento (cioè indirettamente scrive nella variabile globale del nome specificato). La variabile globale può essere successivamente recuperata direttamente.
Ci sono alcune cose speciali da notare:
- Una classe di wrapper stream implementata dovrebbe essere simile a questa , ma in base ai test con il metodo magic
__call
, solostream_open
,stream_write
estream_close
vengono richiamati dalle funzioni interne. - Non sono richiesti contrassegni nella chiamata
fopen
, ma è necessario almeno passare una stringa vuota. Questo perché la funzionefopen
aspetta tale parametro e, anche se non lo si utilizza nell'implementazionestream_open
, è ancora necessario un dummy. - Secondo i test,
stream_write
è chiamato più volte. Ricorda di usare.=
(Assegnazione concatenazione), non=
(assegnazione diretta delle variabili).
Esempio di utilizzo
Nel tag HTML <img>
, è possibile fornire direttamente un'immagine anziché utilizzare un collegamento esterno:
echo '<img src="data:image/png;base64,' . base64_encode($binary) . '">';
Ritaglio e ridimensionamento dell'immagine
Se hai un'immagine e desideri creare una nuova immagine, con nuove dimensioni, puoi utilizzare la funzione imagecopyresampled
:
per prima cosa crea una nuova image
con le dimensioni desiderate:
// new image
$dst_img = imagecreatetruecolor($width, $height);
e memorizzare l'immagine originale in una variabile. Per fare ciò, è possibile utilizzare una delle funzioni createimagefrom*
dove * sta per:
- jpeg
- gif
- png
- stringa
Per esempio:
//original image
$src_img=imagecreatefromstring(file_get_contents($original_image_path));
Adesso copia tutta (o parte) dell'immagine originale (src_img) nella nuova immagine (dst_img) di imagecopyresampled
:
imagecopyresampled($dst_img, $src_img,
$dst_x ,$dst_y, $src_x, $src_y,
$dst_width, $dst_height, $src_width, $src_height);
Per impostare le dimensioni src_*
e dst_*
, utilizza l'immagine seguente:
Ora, se vuoi copiare l'intera immagine (iniziale) di origine, in tutta l'area di destinazione (nessun ritaglio):
$src_x = $src_y = $dst_x = $dst_y = 0;
$dst_width = $width;// width of new image
$dst_height = $height; //height of new image
$src_width = imagesx($src_img); //width of initial image
$src_height = imagesy($src_img); //height of initial image