Áttetsző képek kezelése PHP alatt
Aki már dolgozott PHP alatt áttetsző képekkel (azaz olyan képekkel, amelyek részben átlátszóak), az tudhatja, hogy a beépített GD rendszer nem igazán segíti munkáját. A GD2 bevezetésével ugyan javultak a dolgok, de messze van még a rendszer attól, hogy igazán jól használható legyen áttetsző képek kezelésében.
Az odáig rendben van, hogy nagyszerűen kezelhetünk benne nem áttetsző képeket, erre minden lehetőségünk megvan. Ugyanakkor áttetsző képek esetén a következő problémákba ütközünk:
- Ha a képünk áttetsző, akkor a rendszer hajlamos eldobni az átlátszóságot a pixelekről, azaz pixelenként csak 24 bitet használ.
- Nincs támogatás arra, hogy egy már áttetsző képnek módosítsuk az átlátszóságát.
Áttetsző képek esetén a legfontosabb, hogy egy olyan üres vászonnal (képpel) kezdjünk a munkát, ami true color, és csak átlátszó pixeleket tartalmaz. Ehhez írtam egy egyszerű, de nagyszerű függvényt, ami ezt szépen megvalósítja:
- /**
- * Create a new true color image with solid color background.
- *
- * @param $width
- * The image's width.
- * @param $height
- * The image's height.
- * @param $color
- * 24 bit color of the background.
- * @param $opacity
- * Opacity of the background from 0 to 100 where 100 means totally opaque
- * and 0 is transparent.
- * @return
- * An image link resource.
- */
- function image_generate($width, $height, $color = 0, $opacity = 100) {
- $im = imagecreatetruecolor($width, $height);
- // Handle transparency.
- imagealphablending($im, true);
- imagesavealpha($im, true);
- // Generate RGBA components for the color.
- $r = ($color >> 16) & 0xFF;
- $g = ($color >> 8) & 0xFF;
- $b = $color & 0xFF;
- // $a is between 0 - 127 where 0 is totally opaque and 127 is transparent.
- $a = 127 - round(127 * $opacity / 100);
- if ($a) {
- $fill = imagecolorallocatealpha($im, $r, $g, $b, $a);
- } else {
- $fill = imagecolorallocate($im, $r, $g, $b);
- }
- // Fill the background, and prepare for drawing.
- imagefill($im, 0, 0, $fill);
- imageantialias($im, true);
- return $im;
- }
Az image_generate()
függvény az imagecreatetruecolor()
függvény segítségével létrehoz egy true color képet, majd azt kiszínezi a megfelelő színűre. Amennyiben az $opacity
értéknek 0-t adunk meg, akkor teljesen átlátszó képet kapunk, ekkor a szín mellékessé válik. Vagyis csak válna, ugyanis például az imagecopymerge()
függvény, ha megadunk neki 0 és 127 közötti $ptc
értéket (azaz átlátszóságot), akkor, mivel ez a függvény eldobja a kép eredeti áttetszőségre vonatkozó információit, ezzel a teljesen átlátszatlan színnel fogja másolni a képet. Azaz, ha az áttetsző színünk, amivel a vásznat kiszíneztük fekete volt, akkor az átlátszatlan feketévé, ha fehér, akkor fehérré válik.
A függvény még beállít pár lényeges információt a képpel kapcsolatban. Ezek pedig a következők:
- A kép tartalmazzon áttetszőséget.
- Tartsa meg az áttetszőségre vonatkozó információt mentéskor.
- A rajta végzett műveletekkor az anti-alias függvényeket is használja (átméretezéskor és áttetsző képek egymásra másolásakor van jelentősége).
Ahhoz, hogy egy egy képnek megváltoztassuk az átlátszóságát, két dolgot kell tennünk. Mivel az imagecopymerge()
, amivel elméletileg az áttetszőséget is tudjuk módosítani (a $ptc
paraméter megadásával), nem működik már korábban is áttetsző képeken, ezért létre kell hozni egy átlátszó vásznat (például az image_generate()
függvény segítségével), majd erre kell pixelenként átmásolni az képünk adatait, miközben azoknak megváltoztatjuk az átlátszóságát. Erre jött létre az imagecopy_opacity()
függvény:
- /**
- * Copy an image to destination with changing it's opacity.
- *
- * @param $dst_im
- * Destination image link resource.
- * @param $src_im
- * Source image link resource.
- * @param $dst_x
- * x-coordinate of destination point.
- * @param $dst_y
- * y-coordinate of destination point.
- * @param $src_x
- * x-coordinate of source point.
- * @param $src_y
- * y-coordinate of source point.
- * @param $src_w
- * Source width.
- * @param $src_h
- * Source height.
- * @param $opacity
- * Opacity from 0 to 100 where 100 means totally opaque 0 is transparent.
- */
- function imagecopy_opacity($dst_im, $src_im, $dst_x, $dst_y, $src_x, $src_y, $src_w, $src_h, $opacity) {
- // Calculate the width/height to be copied based on the source width/height,
- // the destination width/height, and the specified width/height, to only copy
- // available pixels to available destinations.
- $width = min($src_w, imagesx($src_im), imagesx($dst_im) - $dst_x);
- $height = min($src_h, imagesy($src_im), imagesy($dst_im) - $dst_y);
- $alpha = $opacity / 100;
- for ($x = 0; $x < $width; $x++) {
- for ($y = 0; $y < $height; $y++) {
- // Get color at (x, y) pixel on the source, and change it's opacity.
- $color = imagecolorat($src_im, $x + $src_x, $y + $src_y);
- $r = ($color >> 16) & 0xFF;
- $g = ($color >> 8) & 0xFF;
- $b = $color & 0xFF;
- // $a is between 0 - 127 where 0 is totally opaque and 127 is transparent.
- $a = 127 - round((127 - (($color >> 24) & 0x7F)) * $alpha);
- $newcolor = imagecolorexactalpha($dst_im, $r, $g, $b, $a);
- // Set the color at the same pixel on destination.
- imagesetpixel($dst_im, $x + $dst_x, $y + $dst_y, $newcolor);
- }
- }
- }
A függvénynek meg kell adni a cél és a forrás képet, valamint az eltolást ezeken a képeken, a forrás kép másolandó darabját, valamint természetesen az átlátszóságot. A PHP átlátszóságkezelése egy kicsit fura ezen a téren. Ugyanis a dokumentáció nem írja, de az imagecolorat()
függvény a színen kívül visszaadja az átlátszóságot is a 24. bit feletti információban 7 bites pontossággal, azaz 0–127-es skálán, ahol a 0 átlátszatlant, 127 pedig teljesen átlátszót jelent.
Azaz a függvényünk nem tesz mást, mint a megadott régióban végighalad a forráskép összes pixelén, azoknak kiszedi a színinformációját (az átlátszósággal egyetemben), majd az átlátszóságot módosítva felülírja a célképen a megadott pixeleket. Ekkor ugye a régióba eső összes pixel felülírásra kerül, de az eredeti imagecopy()
esetében is pontosan ugyanezt a működést kapjuk. Ezek után, ha ezt a módosított képet használni akarjuk, nem kell mást tennünk, mint az imagecopymerge()
használatával (a $ptc
értéket mellőzve) rámásoljuk arra a képre, amit szeretnénk.
Ahhoz, hogy PHP-ban áttetsző képpel tudjunk dolgozni a következőket kell tennünk tehát:
- Betöltjük a használni kívánt forrás képet az
imagecreatefrom*()
segítségével. - Létrehozunk egy teljesen átlátszó képet (például az
image_generate()
függvény segítségével). - Rámásoljuk forrás képet az átlátszó képre (
imagecopy()
,imagecopymerge()
,imagecopyresampled()
, illetveimagecopy_opacity()
). - Elkezdünk vele dolgozni, mint bármilyen más képpel.
Miért imagecopymerge?
Összefoglaló
Thx
Köszönjük
exec('/usr/local/php/bin/php /home/user/script.php &');
(linuxon/unixon, kulcs az &
If a program is started with this function, in order for it to continue running in the background, the output of the program must be redirected to a file or another output stream. Failing to do so will cause PHP to hang until the execution of the program ends.
Köszönöm a kiegészítést
exec('/usr/local/php/bin/php /home/user/script.php > /home/user/akarmi.txt &');
Nem csak processzor, hanem
Szerintem erről a témáról