Pridajte k obrázku dynamický vodoznak pomocou PHP. Vodoznak s PHP Diagonálny vodoznak php

V niektorých prípadoch je pridanie vodoznakov k obrázkom, ktoré zverejníte na svojom webe, jediným spôsobom, ako ich nejako chrániť pred krádežou. Navyše sa povráva, že takéto vodoznaky lákajú na ďalšiu premávku.

Existuje mnoho spôsobov, ktorými môžete obrázok vodotlačiť pomocou PHP, ale môj klient potreboval aplikačnú metódu, ktorá by umožnila kedykoľvek zmeniť vodoznak na nový.

Ako sa ukázalo, existuje také riešenie.

To zvyčajne používajú ľudia, ktorí vyvíjajú stránky s väčšinou grafickým obsahom.

Voľba metódy vodoznaku

Problém pri implementácii celého tohto neporiadku je výber metódy vodoznaku medzi výkonom a flexibilitou. Perfektné riešenie, ktoré by vyhovovalo každému, jednoducho neexistuje. Preto existuje veľa implementácií.

V mojom prípade si zákazník vyhradzuje právo rebrandingu kedykoľvek a namiesto „Rohy a kopytá“ písať „Kopytá a rohy“... Zvolený spôsob vodoznaku by to mal vydržať tiež.

Podstatou tu popísanej technológie vodoznaku je pridať túto značku vždy, keď sa načítava obrázok. Áno, táto metóda nesie množstvo obmedzení, ktoré môžu výrazne ovplyvniť výkon, ale ako sa hovorí, zákazník má vždy pravdu, a preto ak áno. úloha vyžaduje, aby ste dynamicky aplikovali vodoznak, potom je to presne to, čo musíte urobiť.

Ak má niekto jednoduchší spôsob, ste vítaní v komentároch. Bude to zaujímavé počúvať.

Predtým, ako prinesiem akýkoľvek kód, by som chcel popísať prednosti a uviesť funkčný príklad.

Klady:

  • vodoznak môžete zmeniť najmenej 500 -krát denne;
  • je možné nasadiť do akéhokoľvek CMS (nie je k nemu nijako viazaný).

Mínusy:

  • závisí od výkonu hostiteľa (ak máte veľa obrázkov alebo obrázky s vysokým rozlíšením, môže to server výrazne zaťažiť);
  • skúmajúca myseľ môže váš vodoznak stále odstrániť.

Závery: na umiestnenie malého počtu obrázkov s použitými vodoznakmi je táto metóda perfektná, ale ak sa chystáte otvoriť fotogalériu, bolo by správnejšie hľadať niečo menej zaťažené.

Príklad

Implementácia vodoznaku v PHP

Ako sme sľúbili, na to nepotrebujete žiadne špeciálne znalosti, musíte:

  1. súbor, ktorý je v archíve, a umiestnite ho do koreňového adresára vášho webu;
  2. obrázok, ktorý bude fungovať ako vodoznak, je umiestnený v koreňovom adresári stránky a pomenuje ho (v mojom prípade ide o biely ťah štetcom, takže po kliknutí na odkaz nemusí byť na pozadí vášho prehliadača rozlíšiteľný). Obrázok musí byť presne PNG, pretože obsahuje priehľadnú vrstvu. Ak chcete použiť GIF, musíte súbor upraviť image.php;
  3. na miesto, kde chcete zobraziť obrázok s vodoznakom, umiestnite kód:

To je všetko. Všetci sú spokojní, vy aj zákazník.

Ak chcete k fotografii pridať vodoznak bez obťažovania grafických editorov alebo ho pridať pri odosielaní fotografií na server, potom je tento návod pre vás.

V tomto návode vám ukážem, ako pridať vodoznak k obrázku za behu bez toho, aby ste skutočne zmenili pôvodný obrázok. V prvom rade budete potrebovať obrázok, ktorý použijete ako vodoznak.

Potom vytvoríme hlavičku súboru:

// tento riadok oznámi prehliadaču, že míňame hlavičku obrázka jpg ("content-type: image / jpeg");

Potom sformujeme png obrázok a získame jeho rozmery:

// vytvorenie vodoznaku png $ watermark = imagecreatefrompng ("watermark.png"); // získajte šírku a výšku $ watermark_width = imagesx ($ vodoznak); $ watermark_height = imagesy ($ vodoznak);

To isté urobíme s pôvodným obrázkom, ale iba v formát jpg... Je to bežné pri fotografiách, ktoré sa odovzdávajú prostredníctvom formulára. Postupujeme nasledovne:

// vytvorte obrázok jpg $ image_path = "original.jpg"; $ image = imagecreatefromjpeg ($ image_path); // získajte veľkosť obrázku $ size = getimagesize ($ image_path);

Teraz musíme na obrázok umiestniť vodoznak:

// umiestnite vodoznak vpravo dole. Odsadenie 5 pixlov $ dest_x = $ veľkosť - $ šírka vodoznaku - 5; $ dest_y = $ veľkosť - $ vodoznak_ výška - 5;

Potom nastavíme možnosti prelínania pre oba obrázky:

Imagealphablending ($ image, true); imagealphablending (vodoznak $, pravda);

Nakoniec vytvoríme nový obrázok pomocou parametrov:

// vytvorenie novej obrazovej kópie ($ image, $ vodoznak, $ dest_x, $ dest_y, 0, 0, $ vodoznak_šírka, $ vodoznak_ výška); imagejpeg ($ obrázok);

Je dôležité, aby ste po sebe upratali:

// voľná pamäť imagedestroy ($ image); imagedestroy ($ vodoznak);

Na úpravu priehľadnosti vodoznaku môžete použiť Photoshop.

To je s teóriou všetko. Teraz svoje znalosti uplatníme v reálnom projekte. To všetko musí byť uložené do súboru. Nazýva sa napríklad watermark.php

Hlavička ("content-type: image / jpeg"); // získajte názov obrázku prostredníctvom GET $ image = $ _GET ["image"]; // vytvorenie vodoznaku $ watermark = imagecreatefrompng ("watermark.png"); // získanie výšky a šírky vodoznaku $ watermark_width = imagesx ($ vodoznak); $ watermark_height = imagesy ($ vodoznak); // vytvorte jpg z pôvodného obrázku $ image_path = " / cesta / do / image / priečinok /". $ obrázok; $ image = imagecreatefromjpeg ($ image_path); // ak sa niečo pokazí if ($ image === false) (return false;) $ size = getimagesize ($ image_path); // umiestnite na obrázok vodoznak $ dest_x = $ veľkosť - $ šírka vodoznaku - 5; $ dest_y = $ veľkosť - $ vodoznak_ výška - 5; imagealphablending ($ image, true); imagealphablending (vodoznak $, pravda); // vytvorenie novej obrazovej kópie ($ image, $ vodoznak, $ dest_x, $ dest_y, 0, 0, $ vodoznak_šírka, $ vodoznak_ výška); imagejpeg ($ obrázok); // voľná pamäť imagedestroy ($ image); imagedestroy ($ vodoznak);

Teraz, aby ste ukázali fotografiu s vodoznakom bez zmeny pôvodného obrázku, použite nasledujúci kód.

Jednou zo zaujímavých vecí, ktoré môžete s grafickou knižnicou PHP GD robiť, je trieda, ktorá na obrázok vkladá vodoznaky. Stručne povedané, vodoznak je technológia na ochranu digitálnych obrázkov pred neoprávneným použitím tým, že sa na ne aplikujú vodoznaky alebo podpisy. V dôsledku toho sa dá (a spravidla je) použiť na určenie vlastníka autorských práv na obrázok. Poďme teda ďalej.

Úvod

PHP v tejto fáze svojho vývoja ponúka programátorom široké spektrum funkcií na dynamické generovanie obrázkov a prácu s nimi. V tomto článku vám ukážem techniku ​​vytvárania triedy, ktorá bude vodotlačou vytvárať práve tieto obrázky. Táto trieda bude fungovať s dvoma obrázkami: originálom a vodoznakom. Ako doplnok bol zavedený tretí parameter - naša trieda bude obsahovať alfa premennú. To nám umožní použiť alfa kanál pre náš vodoznak.

Pre referenciu

alfa kanál:časť obrazu, ktorá uchováva informácie o priehľadnosti jednotlivých oblastí obrazu, zatiaľ čo farebné kanály ukladajú informácie o farbe obrázku. V. grafickí editori slúži na maskovanie (ochrana pred úpravami) určitej oblasti obrázku. V niektorých aplikáciách sa nazývajú priehľadné masky.

Informácie v alfa kanáli najčastejšie predstavujú vybrané oblasti - určitý tvar alebo usporiadanie farebných oblastí. Ponechaním alfa kanála v obraze sa veľkosť súboru zvýši o 1/3. Obrázky RGB môžu mať až 24 kanálov alfa. Bitmapové a indexované obrázky nemôžu obsahovať alfa kanály.

Prvá časť - základy

Predtým, ako začneme písať samotnú triedu, pozrime sa na funkcie, ktoré v nej budú použité. Tu je ich zoznam:

# vráti šírku a výšku obrázku imagesx () imagesy () # vytvorí nový obrázok true-color imagecreatetruecolor # vráti asociatívne pole s klávesmi červená, zelená a modrá (+ alfa kanál) obsahujúce zodpovedajúce hodnoty pre zadaný index farieb colorcolorsforindex () # vráti index farby pixelu na určenom mieste v obrázku imagecolorat () # nakreslí jeden pixel určenej farby imagesetpixel () # vráti index indexu farby farby v palete obrázku, identifikátor farby (zložený z komponentov RGB) a farebný index palety obrázku, ktorý je „najbližšie“ k hodnote RGB (tieto údaje sú potrebné pre funkciu imagesetpixel ()) imagecolorexact () imagecolorallocate () imagecolorclosest ()

Ako vidíte, php má dostatok funkcií na prácu s grafikou. Aj keď účel niektorých z nich nie je teoreticky celkom jasný, v praxi je všetko oveľa jednoduchšie. Preto, aby sme zistili, ako s nimi pracovať, ich použijeme v našej triede.

Voľba cesty k cieľu

Teraz, keď sme sa už rozhodli pre účel nášho „miniprojektu“, vráťme sa trocha späť a porozprávajme sa o spôsoboch jeho implementácie.

Najprv naša aplikácia dostane dva obrázky - pôvodný obrázok a samotný vodoznak. Ďalej musíme určiť rozmery týchto obrázkov (šírka-šírka a výška-výška). Tieto údaje potrebujeme na umiestnenie vodoznaku do stredu obrázku (za predpokladu, že veľkosť vodoznaku bude menšia ako samotný obrázok).

Potom budeme musieť náš vodoznak prekrývať na pôvodnom obrázku. Aby sme to urobili, musíme pridať farby (matematicky) prekrývajúcich sa obrázkov, aby sme získali tretí.

A nakoniec budeme musieť výsledný obrázok zobraziť v prehliadači. V takom prípade sa obrázok otvorí priamo zo zdroja uvedeného v časti " "

Myslím si, že teória je už dosť - kľúčové body v nej sú dostatočne podrobne odhalené. Teraz prejdeme priamo k napísaniu scenára.

Druhá časť - písanie scenára

Začnime najjednoduchšou vecou - napíšte triedu, ktorá vytvorí súbor s vodoznakom. Nazvime ho „vodoznak“ a jeho kód napíšeme do súboru „api.watermark.php“. „Kostra“ triedy bude mať tri funkcie:

Ďalším krokom je napísanie kódu pre funkcie triedy "vodoznak". Doplňte súbor „api.watermark.php“ nasledujúcimi riadkami kódu:

# funkcia, ktorá spája dva zdrojové obrázky do jednej funkcie create_watermark ($ main_img_obj, $ watermark_img_obj, $ alpha_level = 100) ( # preložte hodnotu priehľadnosti kanála alfa z% na desiatky $ alpha_level / = 100; # vypočítajte rozmery obrázku (šírka a výška) ) $ main_img_obj_w = imagesx ($ main_img_obj); $ main_img_obj_h = imagesy ($ main_img_obj); $ watermark_img_obj_w = imagesx ($ watermark_img_obj); $ vodoznak_img_g ceil (($ main_img_obj_w / 2) + ($ watermark_img_obj_w / 2)); $ main_img_obj_min_y = floor (($ main_img_hobj_h / watermark); $ main_img_obj_max_y = ceil (($ main_img_obj_h / 2) + vytvorenie nového obrázku $ return_img = imagecreatetruecolor ($ main_img_obj_w, $ main_img_obj_h); # prechod cez zdrojový obrázok „obrázok s vodoznakom vrátiť $ return_img; ) # koniec funkcie create_watermark ()

Teraz sa pozrime bližšie na funkciu create_watermark ().

Najprv mu odovzdáme tri parametre:

# pôvodný obrázok má byť vodoznakom $ main_img_obj # samotný vodoznak musí obsahovať alfa kanál $ watermark_img_obj # hodnota priehľadnosti alfa kanála vodoznaku (0-100, predvolené = 100) $ alpha_level

(Je dôležité si uvedomiť, že naša funkcia prijíma obrázky ako objekty, nielen cesty k nim - ale o tom neskôr)

Ďalším krokom je vytvorenie nového obrazu v skutočných farbách s rovnakými rozmermi ako pôvodný obrázok. Tento obrázok (premenná $ return_img) bude použitý na kombináciu informácií z pôvodných obrázkov (obrázok a vodoznak).

Predtým však ešte musíte „prejsť“ každým z dvoch pôvodných obrázkov a „zlúčiť“ ich do jedného. Na to je však ešte priskoro - ešte nie sme na to pripravení. Namiesto toho uverejníme komentár „nejaký kód“ a potom na to miesto pridáme kód.

Posledným krokom je zobrazenie nášho upraveného obrázku na webovej stránke, ktorá to vyžaduje. Ďalej zvážte zostávajúce dve pomocné funkcie.

Tretia časť - pomocné funkcie

Okrem funkcie create_watermark sú v našej triede vodoznakov ešte ďalšie dve funkcie. Pokračujme v zdrojovom kóde triedy nasledujúcimi riadkami:

# priemerovanie dvoch farieb na základe funkcie priehľadnosti alfa _get_ave_color ($ color_a, $ color_b, $ alpha_level) (spätné kolo (((($ color_a * (1- $ alpha_level)) + ($ color_b * $ alpha_level))))) návrat hodnoty najbližších RGB komponentov novej obrazovej funkcie _get_image_color ($ im, $ r, $ g, $ b) ($ c = imagecolorexact ($ im, $ r, $ g, $ b); ak ($ c! = - 1) vráti $ c; $ c = imagecolorallocate ($ im, $ r, $ g, $ b); ak ($ ​​c! = - 1) vráti $ c; vráti imagecolorclosest ($ im, $ r, $ g, ​​$ b);)

A teraz ďalšie podrobnosti. Naša prvá funkcia „_get_ave_color“ má číselné hodnoty pre dve farby a alfa kanál. Vráti ich priemernú hodnotu. Túto funkciu potrebujeme na určenie farby, ktorá sa získa pri superponovaní pixelov dvoch obrázkov.

Druhá funkcia „_get_image_color“ rozdeľuje obrázok na červenú, zelenú a modrú zložku (paleta rgb). So vstavaným funkcie php na prácu s grafikou (boli popísané na začiatku článku), získame pre nový obrázok najbližšiu hodnotu farby.

Okrem toho sa stále overuje niekoľko bodov. Po prvé, ak bolo možné získať presnú hodnotu (premenná $ c), potom sa vráti z funkcie (vráti $ c). V opačnom prípade sa vykoná pokus o zladenie farby pomocou funkcie imagecolorallocate (). Ak to nepomôže k dosiahnutiu výsledku, potom sa pomocou funkcie imagecolorclosest () jednoducho vráti najbližšia hodnota farby (najpresnejšia).

Naša trieda je takmer pripravená. Zostáva len nahradiť komentár „nejaký kód“ vo funkcii „create_watermark“ nasledujúcimi riadkami:

# prechádzajte obrázkom pre ($ y = 0; $ y< $main_img_obj_h; $y++) { for ($x = 0; $x < $main_img_obj_w; $x++) { $return_color = NULL; # определение истинного расположения пикселя в пределах # нашего водяного знака $watermark_x = $x - $main_img_obj_min_x; $watermark_y = $y - $main_img_obj_min_y; # выбор информации о цвете для наших изображений $main_rgb = imagecolorsforindex($main_img_obj, imagecolorat($main_img_obj, $x, $y)); # если наш пиксель водяного знака непрозрачный if ($watermark_x >= 0 && $ vodoznak_x< $watermark_img_obj_w && $watermark_y >= 0 && $ watermark_y< $watermark_img_obj_h) { $watermark_rbg = imagecolorsforindex($watermark_img_obj, imagecolorat($watermark_img_obj, $watermark_x, $watermark_y)); # использование значения прозрачности альфа-канала $watermark_alpha = round(((127-$watermark_rbg["alpha"])/127),2); $watermark_alpha = $watermark_alpha * $alpha_level; # расчет цвета в месте наложения картинок $avg_red = $this->_get_ave_color ($ main_rgb ["red"], $ watermark_rbg ["red"], $ watermark_alpha); $ avg_green = $ this -> _ get_ave_color ($ main_rgb ["green"], $ watermark_rbg ["green"], $ watermark_alpha); $ avg_blue = $ this -> _ get_ave_color ($ main_rgb ["blue"], $ watermark_rbg ["blue"], $ watermark_alpha); # pomocou prijatých údajov vypočítajte index farieb $ return_color = $ this -> _ get_image_color ($ return_img, $ avg_red, $ avg_green, $ avg_blue); # ak nemôžete vybrať farbu, vezmite si # kópiu pôvodného pixelu) else ($ return_color = imagecolorat ($ main_img_obj, $ x, $ y);) # nakreslite nový obrázok z výsledných pixelov imagesetpixel ( $ return_img, $ x, $ y, $ return_color); )))

Po napísaní tak významnej časti kódu sa môžete zastaviť a pozastaviť sa nad jeho analýzou podrobnejšie.

Náš skript najskôr prejde obraz pomocou dvoch slučiek. Paralelne sa stále vypočítavajú súradnice každého pixelu vodoznaku.

Ďalším krokom je vyhľadanie informácií o RGB pre každý pixel. Ak sa aktuálny pixel nenachádza v oblasti priesečníka pôvodného obrázku a vodoznaku, potom naša trieda iba duplikuje pixel pre nový obrázok. Ak sa pixel nachádza v oblasti priesečníka, musíme určiť jeho farbu v dôsledku prekrývania pôvodného obrázku a vodotlače.

Na určenie farby oblasti priesečníka musíme najskôr získať hodnotu premennej RGB vodoznaku pomocou informácií, ktoré sme získali v slučkách „pre“. Potom pomocou funkcie "_get_ave_color" sa stanoví priemerná hodnota farby pre nový obrázok. Ďalej nasleduje funkcia „_get_image_color“ na definovanie farebnej schémy, ktorú bude používať funkcia „return_img“.

Výsledkom je, že po dokončení slučiek „pre“ máme hotový obrázok s vodoznakom.

Teraz sa pozrime na triedu v akcii.

Štvrtá časť - skúšobná jazda

Najprv potrebujeme dva súbory. Pomenujme ten prvý „watermark_test.php“ a vložte doň nasledujúci kód:



Účel tohto súboru je veľmi jednoduchý: zobrazuje v prehliadači pôvodný (main.jpg) a prijatý (watermark.png, s vodoznakom) obrázok.

Ako vidíte, náš druhý obrázok (watermark.png) odkazuje na súbor php image.php, nie na súbor s obrázkom. Tento odkaz vyzerá ako požiadavka GET, kde sú hodnoty dvoch premenných odoslané do súboru php: $ main a $ watermark.

Pomenujme druhý súbor „image.php“ a umiestnime doň nasledujúci kód:

create_watermark ($ main_img_obj, $ watermark_img_obj, 66); # zobrazte v prehliadači náš výsledný obrázok - # ale najskôr mu povedzte, že sa jedná o hlavičku súboru jpeg („Content -Type: image / jpeg“); hlavička ("Content-Disposition: inline; filename =". $ _GET ["src"]); imagejpeg ($ return_img_obj, "", 50); ?>

Tak sme sa dostali do finále. (ZIP, 47,6 kB)

Vlastníci stránok (fóra, diskusné fóra atď.) Často čelia problému s vytváraním vodoznakov na všetkých veľkých obrázkoch stránok.

Tento problém je samozrejme možné vyriešiť ručným vytvorením vodoznaku na každom obrázku, ale jednak to trvá veľa času, a jednak je potrebné uložiť dve verzie obrázka s vodoznakom a bez neho.

Riešením tohto problému môže byť dynamické nanesenie vodoznaku na obrázok pred jeho prenosom návštevníkovi webu.

Na internete existuje riešenie tohto problému vo forme dvoch súborov, ktorých obsah je uvedený nižšie.
Zdroj súbor ".htaccess"

DirectoryIndex index.php RewriteEngine On RewriteCond% (REQUEST_FILENAME) -f RewriteRule ^ (. *) $ /Watermark/_watermark.php

Zdrojový kód súboru "_watermark.php"

250) && ($ info_o> 250)) (// Pre obrázky bez alfa kanála // Posledným parametrom funkcie je nepriehľadnosť vodoznaku imageCopyMerge ($ out, $ vodoznak, ($ info_o- $ info_w)/ 2 , ($ info_o - $ info_w) / 2, 0, 0, $ info_w, $ info_w, 25); // Pri obrázkoch s alfa kanálom // V tomto prípade je priehľadnosť riadená alfa kanálom samotného obrázka // imageCopy ($ out, $ vodoznak, ($ info_o- $ info_w) / 2, ($ info_o- $ info_w) / 2, 0, 0, $ info_w, $ info_w);) prepínač ($ info_o) (prípad 1 : imageGIF ($ out); break; case 2: imageJPEG ($ out); break; case 3: imagePNG ($ out); break; default: return false;) imageDestroy ($ out); imageDestroy (pôvodný $); imageDestroy ($ vodoznak); návrat true; )?>

Riešenie je nasledovné, súbor ".htaccess" je umiestnený v adresári so súbormi obrázkov. Okrem toho je na serveri vytvorený priečinok „vodoznak“, ktorý obsahuje súbor skriptu „_watermark.php“ a skutočný súbor vodoznaku „watermark.png“.

Zároveň som vykonal menšie zmeny v oboch textových súboroch v porovnaní s pôvodnou verziou, s ktorou som sa stretol na internete.

Htaccess súbor, regulárny výraz vyhľadávanie súborov s obrázkom pridalo rozšírenie „jpeg“, ktoré je tiež bežné.

Skript „_watermark.php“ bol prepracovaný tak, aby umiestnil vodoznak do stredu obrázku (vyžadovali to špecifiká riešeného problému) a bola pridaná možnosť upravovať priehľadnosť vytvoreného vodoznaku (komentáre v telo skriptu vám pomôže nastaviť tento parameter sami).

Mali by ste tiež venovať pozornosť skutočnosti, že umiestnením priečinka „vodoznak“ do priečinka s obrázkami, ako radia pôvodné zdroje, nedosiahneme požadovaný výsledok. v tomto prípade budeme musieť mať v každom priečinku vlastný súbor „.htaccess“ a priečinok „vodoznak“. Dôvodom je, že súbor ".htaccess" určuje absolútne cesty od koreňového adresára webu k súboru "_watermark.php". Ak teda v každom priečinku s obrázkami budeme mať podpriečinok „vodoznak“, ak je potrebné zmeniť vodoznak (alebo skript, ktorý ho na obrázku prekrýva), budeme musieť vykonať zmeny vo všetkých priečinkoch.

Aby ste sa tomuto problému vyhli, odporúčam vytvoriť priečinok „vodoznaku“ v koreňovom adresári webu a vložiť súbor „.htaccess“ do adresárov obrázkov bez toho, aby ste ho museli zakaždým meniť. V takom prípade budeme musieť na zmenu vodoznaku alebo skriptu vykonať zmeny iba na jednom mieste na webe. V takom prípade môžete vytvoriť rôzne vodoznaky pre rôzne priečinky s obrázkami odkazovaním z rôznych súborov „.htaccess“ na rôzne skripty, napríklad „_watermark-1.php“, „_watermark-2.php“ atď.

Aby sme to zhrnuli, môžeme povedať, že na prekrytie vodoznakov na všetkých obrázkoch stránky je potrebné stiahnuť nižšie priložený archív, rozbaliť ho, umiestniť priečinok „vodoznak“ do koreňového adresára webu a nahradiť „vodoznak. png "súbor vodoznaku s vlastným a umiestnite súbor" .htaccess "do týchto adresárov stránok, obrázky, z ktorých by mali byť označené vodoznakom.

Tu si môžete stiahnuť archív so všetkými potrebnými súbormi