5 варіантів додавання watermark (водяний знак) на зображення, засобами PHP
Даний пост містить п'ять прикладів, варіантів, додавання водяного знака на зображення за допомогою PHP. Думаю про користь додавання watermark'а все в курсі, в першу чергу це своєрідний захист зображення від несанкціонованого копіювання його і подальше використання на інших сайтах. По-друге, додавання ненав'язливого водяного знака це хороший спосіб зайвий раз прорекламувати свій сайт (бренд, фірму) користувачеві, який не завжди читає текст, але завжди дивиться картинки.
Всі приклади, скрипти використовувалися мною в різних проектах, частина їх була знайдена в мережі, щось було істотно перероблено, щось залишено без змін.
І так приступимо.
Приклад 1. Цей вельми простий скрипт можна віднести до офіційних прикладів, він розміщений на php.net. Все гранично просто. на одне зображення накладається інше (PNG з прозорістю).
// Завантаження штампа і фото, для якого застосовується водяний знак (називається штамп або печатку) $ stamp = imagecreatefrompng ( 'Stamp.png'); $ Im = imagecreatefromjpeg ( 'Photo.jpeg'); // Установка полів для штампа і отримання висоти / ширини штампа $ marge_right = 10; $ Marge_bottom = 10; $ Sx = imagesx ($ Stamp); $ Sy = imagesy ($ Stamp); // Копіювання зображення штампа на фотографію за допомогою зміщення краю // і ширини фотографії для розрахунку позиціонування штампа. imagecopy ($ Im, $ stamp, imagesx ($ Im) - $ sx - $ marge_right, imagesy ($ Im) - $ sy - $ marge_bottom, 0, 0, imagesx ($ Stamp), imagesy ($ Stamp)); // Висновок і звільнення пам'яті header ( 'Content-type: image / png'); imagepng ($ Im); imagedestroy ($ Im);
Приклад 2. Більш зручний у використанні, тому що вдає із себе функцію. Приклад показує як можна додати watermark, просто написавши потрібний текст на зображенні.
function add_watermark ($ img, $ text, $ font, $ r = 128, $ g = 128, $ b = 128, $ alpha = 100) {// отримуємо ширину і висоту вихідного зображення $ width = imagesx ($ Img); $ Height = imagesy ($ Img); // кут повороту тексту $ angle = - rad2deg ( atan2 ((- $ height), ($ width))); // додаємо прогалини до рядка $ text = "". $ Text. ""; $ C = imagecolorallocatealpha ($ Img, $ r, $ g, $ b, $ alpha); $ Size = (($ width + $ height) / 2) * 2 / strlen ($ Text); $ Box = imagettfbbox ($ Size, $ angle, $ font, $ text); $ X = $ width / 2 - abs ($ Box [4] - $ box [0]) / 2; $ Y = $ height / 2 + abs ($ Box [5] - $ box [1]) / 2; // записуємо рядок на зображення imagettftext ($ Img, $ size, $ angle, $ x, $ y, $ c, $ font, $ text); return $ img; }
Параметри функції наступні
$ Img - ідентифікатор зображення, на яке додається водяний знак
$ Text - текст напису
$ Font - ім'я файлу шрифту .ttf
$ R, $ g, $ b - колір напису в форматі RGB
$ Alpha - рівень прозорості, від 0 до 128
Приклад виклику функції:
Приклад 3. Не погана функція, але працює з глобальної змінної зберігає адресу зображення яке буде накладатися на вихідне (адреса watermark'а). Варіант на любителя.
/ ** * Накладення водяного знака у вигляді зображення * @param $ oldimage_name - вихідне зображення * @param $ new_image_name - вихідне зображення * @return Boolean * / function watermark_image ($ oldimage_name, $ new_image_name) {// отримуємо ім'я зображення, використовуваного в як водяний знак global $ image_path; // отримуємо розміри вихідного зображення list ($ Owidth, $ oheight) = getimagesize ($ Oldimage_name); // задаємо розміри для вихідного зображення $ width = 600; $ Height = 300; // створюємо вихідне зображення розмірами, зазначеними вище $ im = imagecreatetruecolor ($ Width, $ height); $ Img_src = imagecreatefromjpeg ($ Oldimage_name); // накладення на вихідне зображення, вихідного imagecopyresampled ($ Im, $ img_src, 0, 0, 0, 0, $ width, $ height, $ owidth, $ oheight); $ Watermark = imagecreatefrompng ($ Image_path); // отримуємо розміри водяного знака list ($ W_width, $ w_height) = getimagesize ($ Image_path); // визначаємо позицію розташування водяного знака $ pos_x = $ width - $ w_width; $ Pos_y = $ height - $ w_height; // накладаємо водяний знак imagecopy ($ Im, $ watermark, $ pos_x, $ pos_y, 0, 0, $ w_width, $ w_height); // зберігаємо вихідне зображення, вже з водяним знаком у форматі jpg і якістю 100 imagejpeg ($ Im, $ new_image_name, 100); // знищуємо зображення imagedestroy ($ Im); unlink ($ Oldimage_name); return true; }
Приклад 4. Приклад додавання водяного знака з 8 бітного PNG файлу. Оформлений в клас (автор вважав це забавним).
/ * * @Param $ main_img_obj - ідентифікатор зображення, на яке додається напис * @param $ watermark_img_obj - ід. зображення прозорого png8 * @param $ alpha_level - прозорість (0 - прозоре, 100 - повністю непрозоре) * @return $ main_img_obj - покажчик зображення * / class watermark2 {function create_watermark ($ main_img_obj, $ watermark_img_obj, $ alpha_level = 100) {$ watermark_width = imagesx ($ Watermark_img_obj); $ Watermark_height = imagesy ($ Watermark_img_obj); $ Dest_x = imagesx ($ Main_img_obj) - $ watermark_width - 5; $ Dest_y = imagesy ($ Main_img_obj) - $ watermark_height - 5; imagecopymerge ($ Main_img_obj, $ watermark_img_obj, $ dest_x, $ dest_y, 0, 0, $ watermark_width, $ watermark_height, $ alpha_level); return $ main_img_obj; }}
Приклад виклику функції:
Приклад 5. Найцікавіший приклад, оформлений в PHP клас. Працює в PNG 24. є можливість налаштування параметрів прозорості. В інтернетах цей варіант викладали і обговорювали не раз.
/ * * @Param $ main_img_obj - ідентифікатор зображення, на яке додається напис * @param $ watermark_img_obj - ід. зображення прозорого png8 * @param $ alpha_level - прозорість (0 - прозоре, 100 - повністю непрозоре) * @return $ main_img_obj - покажчик зображення * / class watermark3 {# given two images, return a blended watermarked image function create_watermark ($ main_img_obj, $ watermark_img_obj, $ alpha_level = 100) {$ alpha_level / = 100; # Convert 0-100 (%) alpha to decimal # calculate our images dimensions $ main_img_obj_w = imagesx ($ Main_img_obj); $ Main_img_obj_h = imagesy ($ Main_img_obj); $ Watermark_img_obj_w = imagesx ($ Watermark_img_obj); $ Watermark_img_obj_h = imagesy ($ Watermark_img_obj); # Determine center position coordinates $ main_img_obj_min_x = floor (($ 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 = floor (($ 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)); # Create new image to hold merged changes $ return_img = imagecreatetruecolor ($ Main_img_obj_w, $ main_img_obj_h); # Walk through main image for ($ y = 0; $ y <$ main_img_obj_h; $ y ++) {for ($ x = 0; $ x <$ main_img_obj_w; $ x ++) {$ return_color = NULL; # Determine the correct pixel location within our watermark $ watermark_x = $ x - $ main_img_obj_min_x; $ Watermark_y = $ y - $ main_img_obj_min_y; # Fetch color information for both of our images $ main_rgb = imagecolorsforindex ($ Main_img_obj, imagecolorat ($ Main_img_obj, $ x, $ y)); # If our watermark has a non-transparent value at this pixel intersection # and we're still within the bounds of the watermark image if ($ watermark_x> = 0 && $ watermark_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)); # Using image alpha, and user specified alpha, calculate average $ watermark_alpha = round (((127 - $ watermark_rbg [ 'alpha']) / 127), 2); $ Watermark_alpha = $ watermark_alpha * $ alpha_level; # Calculate the color 'average' between the two - taking into account the specified 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); # Calculate a color index value using the average RGB values we've determined $ return_color = $ this -> _get_image_color ($ return_img, $ avg_red, $ avg_green, $ avg_blue); # If we're not dealing with an average color here, then let's just copy over the main color} else {$ return_color = imagecolorat ($ Main_img_obj, $ x, $ y); } # END if watermark # draw the appropriate color onto the return image imagesetpixel ($ Return_img, $ x, $ y, $ return_color); } # END for each X pixel} # END for each Y pixel # return the resulting, watermarked image for display return $ return_img; } # END create_watermark () # average two colors given an alpha function _get_ave_color ($ color_a, $ color_b, $ alpha_level) {return round ((($ Color_a * (1 - $ alpha_level)) + ($ color_b * $ alpha_level))); } # END _get_ave_color () # return closest pallette-color match for RGB values function _get_image_color ($ im, $ r, $ g, $ b) {$ c = imagecolorexact ($ Im, $ r, $ g, $ b); if ($ c! = - 1) return $ c; $ C = imagecolorallocate ($ Im, $ r, $ g, $ b); if ($ c! = - 1) return $ c; return imagecolorclosest ($ Im, $ r, $ g, $ b); } # EBD _get_image_color ()}
Приклад виклику функції:
У висновку, хочеться сказати, що всі приклади по своєму гарні. Деякі підійдуть і для великих проектів, інші ж виручать того, коли все потрібно зробити швидко не витрачаючи час на розбори. Сподіваюся вам буде корисний даний пост.