Ändra storlek och manipulera bilder i PHP (med exempel)

I min tidigare handledning diskuterade vi grundläggande bildmanipulation med PHP GD-biblioteket. I den handledningen gav jag en kort introduktion till biblioteket och visade dig hur man laddar bilder från en fil eller skapar dem från början i PHP. Därefter lärde vi oss hur man beskär, roterar, skala och vända en bild med GD. Jag täckte Imagefilter () funktion för att tillämpa olika filter på bildresurser som laddas i skriptet. Jag nämnde också några användbara funktioner i GD som imagesx () och imagesy () för att få bredden och höjden på den laddade bilden.

I slutet av min senaste GD-handledning lärde du dig hur du använder biblioteket för att automatisera grundläggande uppgifter som att ändra storlek på alla bilder i en katalog eller använda filter som gråskala på dem innan du sparar slutresultatet. Om du aldrig har använt PHP GD-biblioteket tidigare, skulle jag föreslå att du går igenom den inledande artikeln för GD innan du läser den här.

I denna handledning lär vi oss om många fler användbara funktioner i GD och hur de kan användas för att automatisera fler av våra bildhanteringsuppgifter.

Manipulera bilder med hjälp av en konvolutionsmatris

Bortsett från pixlarna vid kanterna är varje pixel i en bild omgiven av åtta andra pixlar. Effekter som oskärpa eller kantdetektering beräknas för varje pixel beroende på pixelns värde och värdena för de omgivande bildpunkterna. I kantdetektering innebär exempelvis en skarp färgförändring att vi har nått kanten på något objekt i bilden. En plötslig förändring från vit till brun i bilden nedan kommer att innebära gränsen för koppen och bordet.

Ett enkelt sätt att ange denna typ av filter är med vad som kallas en "convolution matrix". GD levererar imageconvolution ($ image, $ matris, $ div, $ offset) funktion att tillämpa en 3x3 konvolutionsmatris till en bildresurs $ image

De $ matris parametern är en uppsättning av tre arrays, som var och en innehåller tre float-värden, dvs. det är en 3x3 matris. Det första elementet i den första matrisen multipliceras med färgvärdet för den övre vänstra pixeln. På samma sätt multipliceras det andra elementet i den första matrisen med pixelens färgvärde direkt ovanpå den centrala pixeln. Den sista färgen på pixeln erhålls genom att lägga till resultatet av alla dessa multiplikationer och sedan dela det med $ div för normalisering. Normalisering håller vanligtvis det slutliga färgvärdet under 255.

Som vi har sett, $ div Parametern används som en divisor för resultatet av convolution för att normalisera dess värde. De $ offset Parametern används däremot för att ange ett förskjutningsvärde för alla färger. Du kommer att se hur det påverkar slutresultatet i exemplen nedan.

Konvolutionsexempel

Här är en lista med några olika konvolutionsmatriser som vi har applicerat på bilden av en kopp på ett bord.

Box Blur

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

Boxaskärpa fungerar genom att bara medelvärda varje pixel med sina grannar. Vi bestämmer divisorens värde till 9 eftersom summan av alla element i de tre uppsättningarna är 9.

Skärpa 

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

Skärpa fungerar genom att överdriva skillnaderna mellan varje pixel och dess grannar. Detta gör kanterna lite klarare. Vid skärpa är divisorn fortfarande 1 eftersom summan av alla element i de tre uppsättningarna är 1. 

Utföra i relief

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

Präglingsmatrisen liknar den skärpa matrisen, förutom att värdena är negativa till övre vänster och positiva till höger - det är vad som skapar präglingseffekten. Summan av alla element i fallet med präglingsfällningsmatrisen är 1, så vi behöver inte oroa oss för normalisering eller färgförskjutning.

Kantdetektor

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

Kantdetektering liknar skärpa, men effekten är ännu starkare. Även det ursprungliga värdet av bilden ges inte mer vikt än grannarna, det betyder att vi bara bryr oss om kanterna, inte de ursprungliga soliga färgområdena. 

Med kantdetektering är summan av alla matriselement 0. Det betyder att bilden vi kommer att få kommer mest att vara svart om det inte sker en skarp färgförändring som vanligen förekommer vid objektets kanter. Den främst svarta bilden kan vridas till vit genom att ställa in offset-parametern till 255.

Följande bild visar resultatet av alla dessa konvolutionsmatriser.

Funktioner för bildkopiering

PHP GD har många funktioner för att kopiera en del av en bild och sedan ändra storlek eller slå samman den. När du använder dessa funktioner är det viktigt att komma ihåg att PHP anser det övre vänstra hörnet av en bildresurs som sitt ursprung. En positiv x värdet tar dig till höger om bilden och en positiv y värdet tar dig längre ner.

Den enklaste av dessa funktioner är imagecopy ($ dst_im, $ src_im, $ dst_x, $ dst_y, $ src_x, $ src_y, $ src_w, $ src_h). Det kommer att kopiera källbilden till en destinationsbild. De $ dst_x och $ dst_y Parametrar bestämmer det övre vänstra hörnet, där den kopierade bilden klistras in. De $ src_x, $ src_y, $ src_w, och $ src_h parametrar bestämmer den rektangulära delen av källbilden, som kommer att kopieras till destinationen.

Du kan använda den här funktionen för att beskära bilder genom att skapa en bild från början med imagecreatetruecolor () och kopiera grödriktningen av källbilden till den. Du kan också använda den för att lägga till vattenstämplar på bilder, men du måste komma ihåg att med den här metoden kan storleken på vattenstämpeln inte ändras beroende på storleken på våra bilder.

En lösning på detta problem är att använda imagecopyresized ($ dst_im, $ src_im, $ dst_x, $ dst_y, $ src_x, $ src_y, $ dst_w, $ dst_h, $ src_w, $ src_h) fungera. Den accepterar alla parametrar för imagecopy () och två ytterligare parametrar för att bestämma storleken på destinationsområdet där källbilden kopieras.

De imagecopyresized () funktionen är inte perfekt, eftersom den inte skala upp och ner mycket bra. Du kan dock få bättre resizing av storlek med hjälp av imagecopyresampled () funktion, som accepterar alla samma parametrar.

Kopiera med genomskinlighet

Det finns ytterligare två funktioner relaterade till kopiering av bilder som du hittar mycket användbar: imagecopymerge () och imagecopymergegray ().

Funktionen imagecopymerge ($ dst_im, $ src_im, $ dst_x, $ dst_y, $ src_x, $ src_y, $ src_w, $ src_h, $ pct) liknar imagecopy (), där ytterligare $ pct parameteren bestämmer transparensen för den kopierade bilden. Ett värde på 0 betyder ingen öppenhet och ett värde på 100 betyder fullständig öppenhet. Detta kommer att vara till stor hjälp när du inte vill helt dölja innehållet i huvudbilden bakom ditt vattenstämpel.

De imagecopymergegray () funktion använder å andra sidan den sista parametern för att konvertera källbilden till gråskala. Om den är inställd på 0, kommer källbilden att förlora all sin färg. Om den är inställd på 100, blir källbilden inte opåverkad.

Exempel på bildkopiering

Följande exempel använder imagecopy () funktionen för att vrida den högra halvan av en bild till dess negativa. Vi har redan diskuterat andra funktioner som Imagefilter () och imagescale () används i denna kodbit i den tidigare handledningen.

$ im_php = imagecreatefromjpeg ('fish-mosaic.jpg'); $ im_php = imagescale ($ im_php, 800); $ im_php_inv = imagescale ($ im_php, 800); $ im_width = imagesx ($ im_php); $ im_height = imagesy ($ im_php); bildfilter ($ 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);

Här skapar vi två kopior av originalbilden, som var och en har nedskalats för att vara 800 pixlar breda. Därefter använder vi Imagefilter () funktion för att skapa en negativ av $ img_php_inv bildresurs. Den högra halvan av den här negativa bilden kopieras sedan till originalbilden med hjälp av imagecopy () fungera.

Detta var en mycket grundläggande användning av imagecopy () fungera. Du kan se resultaten nedan. Du kan också dela bilden i mindre avsnitt eller ränder för att skapa mer intressanta bildeffekter. Vi kommer att använda imagecopymergegray () funktion i kodfliken nedan för att skapa mycket fler ränder i den ursprungliga fiskbilden.

$ im_php = imagecreatefromjpeg ('fish-mosaic.jpg'); $ im_php = imagescale ($ im_php, 800); $ im_php_bw = imagescale ($ im_php, 800); $ im_width = imagesx ($ im_php); $ im_height = imagesy ($ im_php); $ stripes = 200; för ($ 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);

Ovannämnda kodexempel använder en liknande strategi i föregående exempel, men den här gången har vi delat bilden i mindre randar, som vänds till gråskala eller förblir oförändrade baserat på värdet av variabeln $ i. När vi har slutfört alla kopieringsfusionsoperationer applicerar vi två filter på bilden för att göra ränderna ut.

Följande bild visar slutresultatet av dessa två funktioner i kombination med olika bildfiltre.

Inbäddning av vattenstämplar eller annan information i bilder

Vissa organisationer lägger till vattenstämplar i sina bilder för att klargöra att de äger bilden. Det hjälper också med varumärkesigenkänning och avskräcker andra från att kopiera bilderna blatant. Tack vare PHP GD är vattenmärkande bilder en enkel uppgift.

$ im_php = imagecreatefromjpeg ('waterfall.jpg'); $ vattenmärke = imagecreatefrompng ('watermark.png'); $ im_width = imagesx ($ im_php); $ im_height = imagesy ($ im_php); $ vattenstämpel = imagescale ($ vattenstämpel, $ im_width / 5); $ wt_width = imagesx ($ vattenstämpel); $ wt_height = imagesy ($ vattenstämpel); imagecopy ($ im_php, $ vattenmärke, 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);

I ovanstående kodsedel har vi skapat två olika bildresurser med imagecreatefromjpeg () för huvudbilden och imagecreatefrompng () för vattenstämpeln respektive. Vi bestämmer bredden och höjden på huvudbilden med hjälp av imagesx () och imagesy () funktioner.

Inte alla bilder som du vill vattenstämpla har samma dimensioner. Om du inte ändrar vattenstämpeln baserat på dimensionerna på huvudbilden kan det se konstigt ut. Ett 200px vattenstämpel kan till exempel se bra ut på en bild på 1000px, men det blir för stort för en 600px bred bild och det kan se lite ut på en 2400px bred bild.

Därför använder vi imagescale () funktion för att alltid hålla vattenstämpeln vid en femtedel av den ursprungliga bildbredden. Vi använder sedan imagecopy () funktion för att placera vattenstämpeln på rätt plats. Här är det slutliga resultatet av ovanstående kodbit.

Förutom vattenmärken kan du också lägga till annan information som den plats där ett fotografi togs eller när ett foto togs.

Slutgiltiga tankar

Efter att ha täckt grunderna för bildmanipulation i vår tidigare handledning lärde vi oss om några andra användbara funktioner i GD-biblioteket. Den första delen av handledningen diskuterade hur vi kan manipulera bilder i PHP med hjälp av konvolutionsmatrisen. Jag visade också några exempel på konvolutionsmatrisoperationen för att hjälpa dig att förstå hur PHP kommer till färgvärdena för olika pixlar.

Den andra delen av handledningen förklarade hur man kopierar och / eller ändrar en del av en bild för att klistra in den någon annanstans. Detta är praktiskt när vi vill lägga till något på en bild som ett vattenstämpel eller en tidstämpel.

Försök använda alla dessa funktioner för att skapa några intressanta bildeffekter!