Portal dla pasjonatów motoryzacji

znak wodny nakładki php. Wybór metody znakowania wodnego

Jedną z interesujących rzeczy, które możesz zrobić z biblioteką graficzną GD PHP, jest klasa, która umieszcza znak wodny na obrazie. Krótko mówiąc, znak wodny to technologia służąca do ochrony obrazów cyfrowych przed nieautoryzowanym użyciem poprzez dodawanie do nich znaku wodnego lub podpisów. W rezultacie może być używany (i najczęściej jest) do ustalenia właściciela praw autorskich do obrazu. Więc przejdźmy dalej.

Wstęp

Na tym etapie rozwoju PHP oferuje programistom szeroki zakres funkcji do dynamicznego generowania i pracy z obrazami. W tym artykule pokażę, jak utworzyć klasę, która będzie znakować te same obrazy znakiem wodnym. Ta klasa będzie działać z dwoma obrazami: oryginalnym i znakiem wodnym. Jako dodatek wprowadzono trzeci parametr – nasza klasa będzie zawierała zmienną alpha. Umożliwi nam to użycie kanału alfa dla naszego znaku wodnego.

Na przykład

kanał alfa (kanał alfa): część obrazu przechowująca informacje o przezroczystości poszczególnych fragmentów obrazu, podczas gdy kanały kolorów przechowują informacje o kolorze obrazu. W edytorach graficznych służy do maskowania (ochrony przed edycją) określonego obszaru obrazu. W niektórych aplikacjach nazywane są przezroczystą maską.

Informacje znalezione w kanale alfa najczęściej przedstawiają najjaśniejsze obszary - pewien kształt lub układ kolorowych obszarów. Zachowanie kanału alfa w obrazie zwiększa rozmiar pliku o 1/3. Obrazy RGB mogą mieć do 24 kanałów alfa. Mapy bitowe i obrazy indeksowane nie mogą zawierać kanałów alfa.

Część pierwsza – podstawy

Zanim przystąpimy do pisania samej klasy, przyjrzyjmy się funkcjom, które będą w niej użyte. Oto ich lista:

# zwraca szerokość i wysokość obrazka imagesx() imagesy() # tworzy nowy obraz w prawdziwych kolorach imagecreatetruecolor # zwraca tablicę asocjacyjną z klawiszami czerwonym, zielonym i niebieskim (+ kanał alfa) zawierającą odpowiednie wartości dla określony indeks koloru imagecolorsforindex() # zwraca indeks koloru piksela w określonym miejscu obrazu imagecolorat() # rysuje pojedynczy piksel o podanym kolorze imagesetpixel() # zwraca indeks indeksu koloru z paletą, czyli identyfikator koloru (składający się z komponentów RGB) oraz indeks kolorów obrazu z paletą, który jest „najbliższy” wartości RGB (dane te są potrzebne dla funkcji imagesetpixel()) imagecolorexact() imagecolorallocate() imagecolorclosest()

Jak widać, php ma wystarczająco dużo funkcji do pracy z grafiką. Chociaż cel niektórych z nich nie jest do końca jasny w teorii, w praktyce wszystko jest znacznie prostsze. Dlatego, aby dowiedzieć się, jak z nimi pracować, zastosujemy je w naszej klasie.

Wybór drogi do celu

Teraz, gdy już ustaliliśmy cel naszego „mini-projektu”, cofnijmy się trochę i porozmawiajmy o sposobach jego realizacji.

Najpierw nasza aplikacja otrzymuje dwa obrazy - oryginalny obraz i sam znak wodny. Następnie musimy określić wymiary tych obrazów (szerokość-szerokość i wysokość-wysokość). Dane te są nam potrzebne do umieszczenia znaku wodnego na środku obrazu (zakładając, że rozmiar znaku wodnego będzie mniejszy niż sam obraz).

Następnie będziemy musieli nałożyć nasz znak wodny na oryginalny obraz. Aby to zrobić, musimy dodać kolory (matematycznie) obrazów nakładek, aby uzyskać trzeci.

Na koniec będziemy musieli wyświetlić wynikowy obraz w przeglądarce. W takim przypadku obraz zostanie otwarty bezpośrednio ze źródła określonego w „ "

Myślę, że teoria już wystarczy - kluczowe punkty są ujawnione wystarczająco szczegółowo. Przejdźmy teraz do pisania scenariusza.

Część druga – pisanie scenariusza

Zacznijmy od najprostszego - napiszmy klasę, która utworzy plik ze znakiem wodnym. Nazwijmy to „znakiem wodnym” i zapiszmy jego kod w pliku „api.watermark.php”. „Szkieletem” klasy będą trzy funkcje:

Kolejnym krokiem jest napisanie kodu dla funkcji klasy „watermark”. Uzupełniamy plik „api.watermark.php” o następujące linie kodu:

# funkcja łącząca dwa obrazy źródłowe w jedną funkcję create_watermark($main_img_obj, $watermark_img_obj, $alpha_level = 100) ( # konwertuje wartość przezroczystości kanału alfa z % na dziesiątki $alpha_level/= 100; # oblicza wymiary obrazka (szerokość i wysokość ) $ main_img_obj_w = imagesx ($ main_img_obj); $ main_img_obj_h = imagesy ($ main_img_obj); $ Watermark_Img_Obj_W = imagesx ($ WATMARM_IMG_OBJ); $ Watermark_Img_Obj_H = imareSy ($ Watermark_Img_Obj); określenie Centrum Centrum Image (($ Main _img_obj_w /2)-($watermark_img_obj_w/2)); $main_img_obj_max_x=ceil(($main_img_obj_w/2)+($watermark_img_obj_w/2)); $main_img_obj_min_y=podłoga(($main_img_obj_h/2)-($watermark_img_obj_h/2 ) ); $main_img_obj_max_y=ceil(($main_img_obj_h/2)+($watermark_img_obj_h/2)); # utwórz nowy obraz $return_img = imagecreatetruecolor($main_img_obj_w, $main_img_obj_h); # przejrzyj oryginalny obraz # "jakiś kod " # wyświetl obraz ze znakiem wodnym return $return_img; ) # koniec funkcji create_watermark().

Przyjrzyjmy się teraz bliżej funkcji create_watermark().

Przede wszystkim przekazujemy do niego trzy parametry:

# obraz źródłowy do znaku wodnego $main_img_obj # sam znak wodny musi zawierać kanał alfa $watermark_img_obj # wartość przezroczystości kanału alfa znaku wodnego, (0-100, domyślnie = 100) $alpha_level

(Ważne jest, aby pamiętać, że nasza funkcja akceptuje obrazy jako obiekty, a nie tylko ścieżki do nich - ale o tym później)

Następnym krokiem jest utworzenie nowego obrazu w prawdziwych kolorach o takich samych wymiarach jak oryginalny obraz. Ten obraz (zmienna $return_img) zostanie użyty do połączenia informacji z oryginalnych obrazów (obraz i znak wodny).

Ale zanim to nastąpi, nadal musisz „przejść” przez każdy z dwóch oryginalnych obrazów i „połączyć” je w jeden. Jest po prostu za wcześnie, aby to zrobić - nie jesteśmy jeszcze na to gotowi. Zamiast tego umieścimy komentarz „trochę kodu”, a następnie dodamy fragment kodu do tego miejsca.

Ostatnim krokiem jest wyświetlenie naszego zmodyfikowanego obrazu na stronie internetowej, która tego zażąda. Następnie rozważ pozostałe dwie funkcje pomocnicze.

Część trzecia - Funkcje pomocnicze

Oprócz funkcji create_watermark nasza klasa znaku wodnego ma jeszcze dwie funkcje. Kontynuujmy kod źródłowy klasy następującymi liniami:

# uśrednianie dwóch kolorów, biorąc pod uwagę przezroczystość funkcji kanału alfa _get_ave_color($color_a, $color_b, $alpha_level) ( return round((($color_a*(1-$alpha_level))+($color_b*$alpha_level) )); ) # zwraca wartości najbliższych składowych RGB nowej funkcji obrazu _get_image_color($im, $r, $g, $b) ( $c=imagecolorexact($im, $r, $g, $ b); if ($c!=- 1) zwróć $c; $c=imagecolorallocate($im, $r, $g, $b); if ($c!=-1) zwróć $c; zwróć obrazkolornajbliższy( $im, $r, $g, $b); )

A teraz bardziej szczegółowo. Nasza pierwsza funkcja „_get_ave_color” przyjmuje wartości liczbowe dwóch kolorów i kanału alfa. Zwraca ich średnią wartość. Potrzebujemy tej funkcji, aby określić kolor, który zostanie uzyskany, gdy piksele dwóch rysunków zostaną nałożone.

Druga funkcja „_get_image_color” dzieli obraz na składowe czerwoną (czerwoną), zieloną (zieloną) i niebieską (niebieską) (paleta rgb). Korzystając z wbudowanych funkcji php do pracy z grafiką (ich opis był na początku artykułu), uzyskujemy najbliższą wartość koloru dla nowego obrazu.

Ponadto sprawdzanych jest jeszcze kilka punktów. Po pierwsze, jeśli udało się uzyskać dokładną wartość (zmienna $c), to jest ona zwracana z funkcji (return $c). W przeciwnym razie podejmowana jest próba dopasowania koloru za pomocą funkcji imagecolorallocate(). Jeśli to nie pomoże osiągnąć wyniku, to za pomocą funkcji imagecolorclosest() po prostu zwracana jest najbliższa wartość koloru (najbardziej niedokładna).

Cóż, nasza klasa jest prawie gotowa. Pozostaje tylko zamienić komentarz „jakiś kod” w funkcji „create_watermark” na następujące wiersze:

# przejdź przez obraz dla ($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 && $znak wodny_x< $watermark_img_obj_w && $watermark_y >= 0 && $znak wodny_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["czerwony"], $watermark_rbg["czerwony"], $watermark_alpha); $avg_green = $this->_get_ave_color($main_rgb["zielony"], $watermark_rbg["zielony"], $watermark_alpha); $avg_blue = $this->_get_ave_color($main_rgb["niebieski"], $watermark_rbg["niebieski"], $watermark_alpha); # na podstawie otrzymanych danych oblicz indeks koloru $return_color = $this->_get_image_color($return_img, $avg_red, $avg_green, $avg_blue); # jeśli nie możesz wybrać koloru, po prostu weź # kopię oryginalnego piksela ) else ( $return_color = imagecolorat($main_img_obj, $x, $y); ) # narysuj nowy obraz z otrzymanych pikseli imagesetpixel( $return_img, $x, $y, $return_color); ))

Po napisaniu tak znaczącej części kodu możesz zatrzymać się i zastanowić nad jego bardziej szczegółową analizą.

Nasz skrypt najpierw przechodzi przez obraz za pomocą dwóch pętli „for”. Równolegle obliczane są również współrzędne każdego piksela znaku wodnego.

Następnie informacje RGB są przeszukiwane dla każdego piksela. Jeśli bieżący piksel nie znajduje się w obszarze, w którym przecinają się oryginalny obraz i znak wodny, nasza klasa powiela tylko piksel dla nowego obrazu. Jeśli piksel znajduje się w obszarze przecięcia, musimy określić jego kolor w wyniku nałożenia oryginalnego obrazu i znaku wodnego.

Aby określić kolor obszaru przecięcia, musimy najpierw uzyskać wartość zmiennej RGB znaku wodnego, korzystając z informacji otrzymanych w pętlach „for”. Następnie za pomocą funkcji „_get_ave_color” określana jest średnia wartość koloru dla nowego obrazu. Następnie pojawia się funkcja „_get_image_color”, która określa schemat kolorów, który będzie używany przez funkcję „return_img”.

W efekcie po wykonaniu pętli „for” mamy gotowy obraz ze znakiem wodnym.

A teraz sprawdźmy naszą klasę w akcji.

Część czwarta - jazda próbna

Aby rozpocząć, potrzebujemy dwóch plików. Nazwijmy pierwszy „watermark_test.php” i umieść w nim następujący kod:



Przeznaczenie tego pliku jest bardzo proste: wyświetla w przeglądarce oryginalne (main.jpg) i wynikowe (watermark.png, watermarked) obrazy.

Jak widać, nasz drugi obraz (watermark.png) odnosi się do pliku php image.php, a nie do pliku obrazu. Link ten wygląda jak żądanie GET, gdzie do pliku php przekazywane są wartości dwóch zmiennych: $main i $watermark.

Nazwijmy drugi plik „image.php” i umieśćmy w nim następujący kod:

create_watermark($main_img_obj, $watermark_img_obj, 66); # wyświetl wynikowy obraz w przeglądarce - # ale najpierw daj znać, że to plik jpeg header("Content-Type: image/jpeg"); header("Dyspozycja treści: inline; filename=" . $_GET["src"]); imagejpeg($return_img_obj, "", 50); ?>

No to dochodzimy do finału. (ZIP, 47,6 KB)

W Internecie jest duża liczba obrazów, które z reguły są przesyłane przez właścicieli witryn lub użytkowników witryn. W zależności od trafności obraz może przenosić się z witryny do witryny. Nie wspominając o prawach autorskich, nie każdemu właścicielowi witryny może podobać się fakt, że obrazy z jego witryny są kopiowane na inne zasoby. Aby walczyć z banalnym kopiowaniem obrazów witryn, wynaleziono nakładanie znaków wodnych na obrazy, wskazując, że obraz należy do określonego zasobu. Może to być szczególnie prawdziwe w przypadku witryn zawierających dużą liczbę unikalnych obrazów.

Przyjrzyjmy się przykładowi kodu, który demonstruje nakładanie znaku wodnego na przesłane obrazy.

Tak więc główne ustawienia są zawarte w postaci stałych i zajmują pierwsze miejsce w kodzie:

// ścieżka obrazu znaku wodnego define("WATERMARK_OVERLAY_IMAGE", "/lab/watermark/watermark.png"); // Kompresja, zakres 0-100 (wpływa na jakość obrazu) define("WATERMARK_OUTPUT_QUALITY", 100); // folder obrazów źródłowych define("UPLOADED_IMAGE_DESTINATION", "/lab/watermark/upload/src/"); // folder z przetworzonymi obrazami define("WATERMARK_IMAGE_DESTINATION", "/lab/watermark/upload/");

Na stronie umieścimy formularz wgrywania zdjęć, który posłuży do przesłania zdjęć na serwer.
Kod formularza:

Wybierz plik obrazu:
oryginalny obraz
"style="maksymalna szerokość: 300px;" />
Obraz ze znakiem wodnym
"style="maksymalna szerokość: 300px;" />

Cóż, teraz najważniejsze są funkcje do przetwarzania obrazu. Umieść te funkcje przed wyświetleniem formularza na stronie.

Dwie kluczowe funkcje, za pomocą jednej obraz jest przesyłany na serwer, za pomocą drugiej nakładany jest znak wodny. Być może komentarze do funkcji są opisane bardziej niż szczegółowo i zbędne byłoby pisanie tego samego tutaj.

Jeśli chcesz dodać znak wodny do zdjęcia bez zawracania sobie głowy edytorami obrazów lub dodawania go podczas przesyłania zdjęć na serwer, ta lekcja jest dla Ciebie.

W tym samouczku pokażę, jak dodać znak wodny do obrazu w locie bez faktycznej zmiany oryginalnego obrazu. Przede wszystkim będziesz potrzebować obrazu, którego użyjesz jako znaku wodnego.

Następnie tworzymy nagłówek pliku:

// ta linia poinformuje przeglądarkę, że przekazujemy obraz jpg header("content-type: image/jpeg");

Następnie tworzymy obraz png i uzyskujemy jego wymiary:

// utwórz znak wodny png $watermark = imagecreatefrompng("watermark.png"); // pobierz szerokość i wysokość $watermark_width = imagesx($watermark); $wodny_wysokość = obrazy($znak wodny);

Zrobimy to samo z oryginalnym obrazem, ale tylko w formacie jpg. Jest to powszechne w przypadku zdjęć przesyłanych za pośrednictwem formularza. Działamy w następujący sposób:

// utwórz obraz jpg $image_path = "original.jpg"; $image = imagecreatefromjpeg($ścieżka_obrazu); // pobierz wymiar obrazu $size = getimagesize($image_path);

Teraz musimy umieścić znak wodny na obrazie:

// umieść znak wodny w prawym dolnym rogu. wypełnienie 5px $dest_x = $rozmiar - $wodny_width - 5; $dest_y = $rozmiar - $znak wodny_wysokość - 5;

Następnie ustawimy opcje mieszania dla obu obrazów:

imagealphablending($obraz, prawda); imagealphablending($znak wodny, prawda);

Na koniec tworzymy nowy obraz za pomocą parametrów:

// utwórz nowy obraz imagecopy($image, $watermark, $dest_x, $dest_y, 0, 0, $watermark_width, $watermark_height); imagejpeg($obraz);

Ważne jest, aby zabrać:

// zwolnij pamięć imagedestroy($image); imagedestroy($znak wodny);

Możesz użyć programu Photoshop, aby dostosować przezroczystość znaku wodnego.

To wszystko z teorią. Teraz zastosujemy naszą wiedzę w prawdziwym projekcie. Wszystko to należy zapisać do pliku. Na przykład o nazwie watermark.php

Header("typ zawartości: obraz/jpeg"); // pobierz nazwę obrazu przez GET $image = $_GET["image"]; // utwórz znak wodny $watermark = imagecreatefrompng("watermark.png"); // pobierz wysokość i szerokość znaku wodnego $watermark_width = imagesx($watermark); $wodny_wysokość = obrazy($znak wodny); // utwórz jpg z oryginalnego obrazu $image_path = "/path/to/image/folder/" . $obraz; $image = imagecreatefromjpeg($ścieżka_obrazu); //jeśli coś pójdzie nie tak if ($image === false) ( return false; ) $size = getimagesize($image_path); // umieść znak wodny na obrazku $dest_x = $size - $watermark_width - 5; $dest_y = $rozmiar - $znak wodny_wysokość - 5; imagealphablending($obraz, prawda); imagealphablending($znak wodny, prawda); // utwórz nowy obraz imagecopy($image, $watermark, $dest_x, $dest_y, 0, 0, $watermark_width, $watermark_height); imagejpeg($obraz); // zwolnij pamięć imagedestroy($image); imagedestroy($znak wodny);

Teraz, aby pokazać zdjęcie, które będzie miało znak wodny bez zmiany oryginalnego obrazu, użyj następującego kodu.

Publikując swoje zdjęcia i filmy w Internecie, podejmujesz duże ryzyko, ponieważ Twoje treści można łatwo skopiować do setek innych witryn. Nie byłoby wspaniale znaleźć swoje zdjęcie do wiadomości, na przykład nad którą ciężko pracowałeś, na innej stronie bez podania źródła, czyli swojej strony, prawda? Delikatnie mówiąc, będziesz zdenerwowany, a gdyby nie było to proste zdjęcie do wiadomości, ale złożona praca w Photoshopie, powiedzieć, że jesteś zły, to nic nie mówić! Co więc możesz zrobić, aby chronić swoją grafikę?

Aby chronić prawa autorskie do obrazów lub filmów w Internecie, dla wygody zwykle stosuje się cyfrowy znak wodny lub cyfrowy znak wodny. Dołącz znak wodny do każdego przesłanego obrazu, aby go zabezpieczyć. CEH może być logo Twojej strony lub firmy, pięknie i estetycznie umieszczonym na przesłanych obrazach.

Stwórzmy najpierw plik zawierający niezbędne ustawienia w postaci stałych - /config.php:

Define("WATERMARK_OVERLAY_IMAGE", "/develop/images/watermark.png"); // Ścieżka do twojego znaku wodnego define("WATERMARK_OUTPUT_QUALITY", 100); // Jakość otrzymanego obrazu ze znaku wodnego. Pamiętaj, że jakość wpływa bezpośrednio na rozmiar pliku. define("UPLOADED_IMAGE_DESTINATION", "/develop/folder1/"); // Ścieżka do lokalizacji początkowo załadowanych obrazów define("WATERMARK_IMAGE_DESTINATION", "/develop/folder2/"); // Ścieżka do obrazów z nałożonym znakiem wodnym

Zbierzmy pliki utworzone powyżej w pliku wykonującym pobieranie /prześlij.php

include("config.php"); include("funkcje.php"); $result = ImageUpload($_FILES["plik_użytkownika"]["nazwa_tmp"], $_FILES["plik_użytkownika"]["nazwa"]); if ($result === false)( echo "Przesyłanie nie powiodło się!"; )

Na przykład, jeśli ładowany obraz to:

Następnie po załadowaniu i zastosowaniu znaku wodnego otrzymasz następujący obraz:

W tym przykładzie przesłany obraz jest zapisywany w jednym folderze, a obraz z cyfrowym znakiem wodnym w innym, dzięki czemu zawsze masz dostęp do oryginalnych obrazów, ale oczywiście należy umieścić obrazy z CEH na stronie .

(178,4 KiB, 989 odsłon)