Redimensionarea și manipularea imaginilor în PHP (cu exemple)

În tutorialul meu anterior, am discutat despre manipularea imaginii de bază utilizând biblioteca PHP GD. În acest tutorial, am prezentat o scurtă introducere în bibliotecă și vă arată cum să încărcați imagini dintr-un fișier sau să le creați din nou în PHP. După aceea, am învățat cum să recoltăm, să rotim, să scarăm și să flipem o imagine folosind GD. Am acoperit imagefilter () funcția de a aplica filtre diferite la resursele de imagine încărcate în script. Am menționat, de asemenea, câteva funcții utile în GD imagesx () și imagesy () pentru a obține lățimea și înălțimea imaginii încărcate.

Până la sfârșitul ultimului meu tutorial GD, ați învățat cum să utilizați biblioteca pentru a automatiza sarcinile de bază, cum ar fi redimensionarea tuturor imaginilor într-un director sau aplicarea de filtre ca tonuri de gri pe ele înainte de a salva rezultatul final. Dacă nu ați folosit niciodată biblioteca PHP GD înainte, aș sugera să treceți prin articolul introductiv GD înainte de ao citi.

În acest tutorial, vom afla multe funcții utile în GD și modul în care acestea pot fi utilizate pentru a automatiza mai multe dintre sarcinile noastre de manipulare a imaginilor.

Manipularea imaginilor utilizând o matrice de convoluție

Cu excepția pixelilor de la margini, fiecare pixel dintr-o imagine este înconjurat de opt alți pixeli. Efectele, cum ar fi neclaritatea sau detectarea marginilor, sunt calculate pentru fiecare pixel în funcție de valoarea pixelului și de valorile pixelilor din jur. În cazul detectării marginilor, de exemplu, o schimbare bruscă a culorii presupune că am ajuns la marginea unui obiect din imagine. De exemplu, o schimbare bruscă de la alb la maron în imaginea de mai jos va însemna limita cuplului și a mesei.

O modalitate ușoară de a specifica acest tip de filtru este cu ceea ce se numește "matricea de convoluție". GD aprovizionează imageconvolution ($ imagine, $ matrix, $ div, $ offset) funcția de a aplica o matrice de convoluție 3x3 la o resursă de imagine $ image

matrice $ parametrul este o matrice de trei tablouri, fiecare dintre ele conținând trei valori flotante - adică. este o matrice 3x3. Primul element al primei matrice este înmulțit cu valoarea de culoare a pixelului de sus-stânga. În mod similar, al doilea element al primei matrice este înmulțit cu valoarea de culoare a pixelului direct deasupra pixelului central. Culoarea finală a pixelului este obținută prin adăugarea rezultatului tuturor acestor multiplicări și apoi prin împărțirea acestora $ div pentru normalizare. Normalizarea menține în general valoarea finală a culorii sub 255.

După cum am văzut, $ div parametru este folosit ca un divizor pentru rezultatul convoluției pentru a-și normaliza valoarea. $ compensate parametrul, pe de altă parte, este utilizat pentru a specifica o valoare de offset pentru toate culorile. Veți vedea cum afectează rezultatul final în exemplele de mai jos.

Exemple de convoluție

Iată o listă a unor matrici de convoluție diferite pe care le-am aplicat imaginii unei cupe de pe masă.

Box Blur

$ box_blur = array ([1, 1, 1], [1, 1, 1], [1, 1, 1]); imageconvolution ($ im_php, $ box_blur, 9, 0);

Blurul de casetă funcționează doar prin media fiecărui pixel cu vecinii săi. Am stabilit valoarea divizorului la 9 deoarece suma tuturor elementelor din cele trei tablouri este de 9.

Ascuţi 

$ sharpen = matrice ([0, -1, 0], [-1, 5, -1], [0, -1, 0]); imageconvolution ($ im_php, $ sharpen, 1, 0); 

Ascuțișul funcționează exagerând diferențele dintre fiecare pixel și vecinii săi. Acest lucru face ca marginile să fie mai clare. În cazul ascuțirii, divizorul este încă 1 deoarece suma tuturor elementelor din cele trei tablouri este de 1. 

Grava

$ emboss = array ([- 2, -1, 0], [-1, 1, 1], [0, 1, 2]); imageconvolution ($ im_php, $ embos, 1, 0);

Matricea de embosare este similară cu matricea de ascuțire, cu excepția faptului că valorile sunt negative la stânga superioară și pozitive la dreapta inferioară - ceea ce creează efectul de embosare. Suma tuturor elementelor în cazul matricei de convoluție a embosului este de 1, deci nu trebuie să ne facem griji în ceea ce privește normalizarea sau decalajul de culoare.

Detectarea muchiilor

$ edge_detect = array ([- 1, -1, -1], [-1, 8, -1], [-1, -1, -1]); imageconvolution ($ im_php, $ edge_detect, 1, 0); imageconvolution ($ im_php, $ edge_detect, 1, 255); 

Detectarea muchiilor este similară cu ascuțirea, dar efectul este și mai puternic. De asemenea, valoarea inițială a imaginii nu este dată mai mult decât vecinii - ceea ce înseamnă că ne pasă doar de margini, nu de zonele originale colorate. 

Cu ajutorul detecției margini, suma tuturor elementelor de matrice este 0. Aceasta înseamnă că imaginea pe care o vom obține va fi în cea mai mare parte negru dacă nu există o schimbare bruscă a culorii, care apare în general la marginile obiectelor. Imaginea cea mai mare parte neagră poate fi transformată în alb prin setarea parametrului de compensare la 255.

Următoarea imagine prezintă rezultatul tuturor acestor matrici de convoluție.

Funcții de copiere a imaginilor

PHP GD are o mulțime de funcții pentru a copia o parte dintr-o imagine și apoi ao redimensiona sau o îmbina. Atunci când utilizați aceste funcții, este important să rețineți că PHP consideră că colțul din stânga sus al unei resurse de imagine este originea sa. Un pozitiv X valoarea vă va duce în dreapta imaginii și o valoare pozitivă y vă va duce mai departe.

Cea mai simplă dintre aceste funcții este imagecopy ($ dst_im, $ src_im, $ dst_x, $ dst_y, $ src_x, $ src_y, $ src_w, $ src_h). Acesta va copia imaginea sursă pe o imagine destinație. $ dst_x și $ dst_y parametrii determină colțul din stânga sus, unde imaginea copiată va fi lipită. $ src_x, $ src_y, $ src_w, și $ src_h parametrii determină porțiunea dreptunghiulară a imaginii sursă, care va fi copiată la destinație.

Puteți utiliza această funcție pentru a decupa imaginile creând o imagine de la zero folosind imagecreatetruecolor () și copierea dreptunghiului de cultură al imaginii sursă în ea. De asemenea, puteți să-l utilizați pentru a adăuga filigran pe imagini, dar trebuie să vă amintiți că prin această metodă, dimensiunea filigranului nu poate fi modificată în funcție de dimensiunea imaginilor.

O soluție la această problemă este folosirea lui ($ dst_im, $ src_im, $ dst_x, $ dst_y, $ src_x, $ src_y, $ dst_w, $ dst_h, $ src_w, $ src_h) funcţie. Acceptă toți parametrii imagecopy () și doi parametri suplimentari pentru a determina dimensiunea zonei de destinație unde va fi copiată imaginea sursă.

imagecopyresized () funcția nu este perfectă, deoarece nu scala imaginea în sus și în jos foarte bine. Cu toate acestea, puteți obține o redimensionare mai bună a calității folosind imagecopyresampled () care acceptă toți aceiași parametri.

Copiați cu transparență

Există două funcții suplimentare legate de copierea imaginilor pe care le veți găsi foarte utile: imagecopymerge () și imagecopymergegray ().

Functia image src_y, $ src_w, $ src_h, $ pct), de exemplu, este similar cu imagecopy (), în cazul în care suplimentare $ PCT parametrul determină transparența imaginii copiate. O valoare de 0 înseamnă lipsa transparenței și o valoare de 100 înseamnă transparență completă. Acest lucru va fi de mare ajutor atunci când nu doriți să ascundeți complet conținutul imaginii principale din spatele filigranului.

imagecopymergegray () funcția, pe de altă parte, utilizează ultimul parametru pentru a converti imaginea sursă în tonuri de gri. Dacă este setat la 0, imaginea sursă își va pierde toată culoarea. Dacă este setat la 100, imaginea sursă va rămâne neafectată.

Exemplu de copiere imagine

Următorul exemplu folosește imagecopy () pentru a transforma jumătatea dreaptă a unei imagini în negativ. Am discutat deja despre alte funcții, cum ar fi imagefilter () și imagescale () utilizat în acest fragment de cod în tutorialul anterior.

$ im_php = imaginecreatefromjpeg ("fish-mosaic.jpg"); $ im_php = imaginile ($ im_php, 800); $ im_php_inv = imaginile ($ im_php, 800); $ im_width = imagesx ($ im_php); $ im_height = imagini ($ im_php); imagefilter ($ im_php_inv, IMG_FILTER_NEGATE); imagecopy ($ im_php, $ im_php_inv, $ im_width / 2; 0; $ im_width / 2; 0; $ im_width / 2; $ im_height); $ new_name = 'fish-mosaic-half-negate.jpg'; imagejpeg ($ im_php, $ new_name);

Aici, creați două copii ale imaginii originale, fiecare dintre acestea diminuându-se până la 800 de pixeli. Apoi, folosim imagefilter () funcția de a crea un negativ al $ img_php_inv resursă imagine. Partea dreaptă a acestei imagini negative este apoi copiată pe imaginea originală folosind imagecopy () funcţie.

Aceasta a fost o utilizare foarte de bază a imagecopy () funcţie. Puteți vedea rezultatele de mai jos. De asemenea, puteți împărți imaginea în secțiuni sau benzi mai mici pentru a crea efecte de imagine mai interesante. Vom folosi imagecopymergegray () funcția din fragmentul de cod de mai jos pentru a crea mai multe dungi în imaginea originală a peștilor.

$ im_php = imaginecreatefromjpeg ("fish-mosaic.jpg"); $ im_php = imaginile ($ im_php, 800); $ im_php_bw = imaginile ($ im_php, 800); $ im_width = imagesx ($ im_php); $ im_height = imagini ($ im_php); $ dungi = 200; pentru ($ i = 0; $ i < $stripes; $i++)  if($i%2 == 0)  imagecopymergegray($im_php, $im_php_bw, $i*$im_width/$stripes, 0, $i*$im_width/$stripes, 0, $im_width/$stripes, $im_height, 0);  else  imagecopymergegray($im_php, $im_php_bw, $i*$im_width/$stripes, 0, $i*$im_width/$stripes, 0, $im_width/$stripes, $im_height, 100);   imagefilter($im_php, IMG_FILTER_CONTRAST, -255); imagefilter($im_php, IMG_FILTER_COLORIZE, 250, 0, 0, 100); $new_name = 'fish-mosaic-stripes.jpg'; imagejpeg($im_php, $new_name);

Exemplul de cod de mai sus utilizează o strategie similară cu cea din precedentul exemplu, dar de data aceasta am împărțit imaginea în dungi mai mici, care sunt transformate în tonuri de gri sau păstrate neschimbate pe baza valorii variabilei $ i. După ce ați terminat toate operațiile de îmbinare a copierii, aplicăm două filtre pe imagine pentru a face ca dungile să iasă în evidență.

Următoarea imagine prezintă rezultatul final al acestor două funcții în legătură cu diferite filtre de imagine.

Încărcarea filigranelor sau a altor informații în imagini

Unele organizații adaugă filigrane imaginilor lor pentru a clarifica faptul că dețin imaginea. De asemenea, ajută la recunoașterea mărcii și descurajează alte persoane să copieze în mod flagrant imaginile. Datorită PHP GD, imaginile cu filigran este o sarcină simplă.

$ im_php = imaginecreatefromjpeg ('waterfall.jpg'); $ watermark = imagecreatefrompng ('watermark.png'); $ im_width = imagesx ($ im_php); $ im_height = imagini ($ im_php); $ watermark = imaginecale ($ watermark, $ im_width / 5); $ wt_width = imagesx ($ filigran); $ wt_height = imagine ($ filigran); imagecopy ($ im_php, $ watermark, 0,95 * $ im_width - $ wt_width, 0,95 * $ im_height - $ wt_height, 0, 0, $ wt_width, $ wt_height); $ new_name = 'waterfall-watermark.jpg'; imagejpeg ($ im_php, $ new_name);

În fragmentul de cod de mai sus, am creat două resurse diferite de imagine folosind imagecreatefromjpeg () pentru imaginea principală și imagecreatefrompng () pentru filigran, respectiv. Determinăm lățimea și înălțimea imaginii principale folosind imagesx () și imagesy () funcții.

Nu toate imaginile pe care doriți să filigranți vor avea aceleași dimensiuni. Dacă nu redimensionați filigranul pe baza dimensiunilor imaginii principale, ar putea părea ciudat. De exemplu, un filigran de 200 de pixeli ar putea să arate bine pe o imagine de 1000 pixeli, dar va fi prea mare pentru o imagine cu dimensiunea de 600 de pixeli și ar putea părea prea mică pe o imagine de 2400 pixeli lățime.

Prin urmare, folosim imagescale () funcția de a păstra întotdeauna filigran la o cincime din lățimea imaginii originale. Apoi folosim imagecopy () pentru a plasa filigranul în locația potrivită. Iată rezultatul final al fragmentului de cod de mai sus.

În afară de filigrane, puteți adăuga și alte informații, cum ar fi locul în care a fost făcută fotografia sau momentul fotografierii.

Gândurile finale

După ce am acoperit elementele de bază ale manipulării imaginilor în tutorialul nostru anterior, am aflat despre câteva funcții utile din biblioteca GD. Prima parte a tutorialului a discutat despre modul în care putem manipula imaginile în PHP utilizând matricea de convoluție. Am arătat, de asemenea, câteva exemple ale operației matricei de convoluție pentru a vă ajuta să înțelegeți cum ajunge PHP la valorile de culoare ale diferitelor pixeli.

A doua parte a tutorialului a explicat cum să copiați și / sau să redimensionați o parte a unei imagini pentru ao lipi în altă parte. Acest lucru este util atunci când dorim să adăugăm ceva la o imagine ca un filigran sau o amprentă de timp.

Încercați să utilizați toate aceste funcții pentru a crea unele efecte interesante de imagine!

Cod