Нанесення водяних знаків на зображення засобами PHP

371

Від автора: у даному уроці ми з Вами розглянемо один із способів нанесення водяного знака на зображення засобами мови PHP. Так як використовуючи водяні знаки на своїх зображеннях, Ви захистите їх від використання іншими користувачами, до того ж, якщо зображення буде використовуватися на інших сайтах, або буде знайдено пошуковою системою — водяний знак, що містить посилання на Ваш ресурс може залучити додатковий трафік.

Нанесення водяних знаків на зображення засобами PHPНанесення водяних знаків на зображення засобами PHP

Постановка задачі

У даному уроці нам з Вами необхідно реалізувати динамічне додавання водяного знака до виводиться на екран зображення. При цьому початкове зображення не повинно бути змінено. А також необхідно зробити так, що б, наприклад, при завантаженні зображень на сервер, через звичайну форму, виконувалося додавання водяних знаків до завантажуваних фотографій.

Для вирішення поставленого завдання, я підготував два зображення: вихідне, на яке ми будемо додавати водяний знак, і, власне, сам водяний знак. В якості вихідного зображення, ми будемо використовувати наступне зображення:

Нанесення водяних знаків на зображення засобами PHP

В якості водяного знака, будемо використовувати наступне зображення:

Нанесення водяних знаків на зображення засобами PHP

Це зображення формату PNG з 50% ступенем прозорості.

Підготовка до написання скрипта

Насамперед необхідно переконатися, що у Вашому інтерпретатор мови PHP підключена бібліотека GD. Ця бібліотека використовується для роботи з зображеннями засобами мови PHP. Тому якщо Ви не впевнені, що ця бібліотека підключена, відкрити конфігураційний файл мови PHP та знайдіть рядок: extension=php_gd2.dll

Напроти цього рядка не повинно бути символу “;”(крапка з комою). Якщо він є, то видаліть його і перезавантажте веб-сервер Apache. Далі, для сьогоднішнього уроку я підготував тестову сторінку, яка відображає на екрані початкове зображення:

Нанесення водяних знаків на зображення засобами PHP

Але якщо ми хочемо динамічно наносити на зображення водяний знак і при цьому не змінювати вихідне зображення, значить, зображення повинне оброблятися скриптом на мові PHP. Тому в тегу img необхідно змінити значення атрибуту src. Тобто значення цього атрибута повинно вказувати не на зображення, а на файл, який обробить початкове зображення і завдасть на нього водяний знак. І звичайно ж поверне нове зображення. Тому перепишемо тег img:

Як Ви бачите, тепер ми звертаємося до файлу image.php, який поверне нам нове зображення, і передаємо йому через GET параметри шлях до вихідного зображення. Перед тим як приступити до створення файлу image.php, який повинен повернути нам нове зображення, давайте створимо файл конфігурації config.php з ось таким вмістом:

Цей фал нам необхідний для зберігання деяких налаштувань, а саме:

DIR_IMG – папка де містяться всі зображення;

WM – шлях до зображення, яке використовується як водяний знак.

Потім створимо ще один файл – functions.php, який буде містити в собі необхідні функції для роботи скрипта. Тепер створимо файл image.php і першим ділом підключимо тільки що створені файли до нього.

include “config.php”;
include “functions.php”;

Далі перевіримо наявність осередку image в суперглобальном масиві $_GET, якщо дана клітинка є, то створимо змінну і збережемо в неї значення комірки:

if($_GET[‘image’]) {
$image_for_wm = DIR_IMG.$_GET[‘image’];
}

Далі викличемо функцію, яка і буде автоматичний додавати водяний знак до зображення (дану функцію ми з Вами ще напишемо):

get_water($image_for_wm);

Тепер переходимо безпосередньо до написання функції get_water(), яка опрацює початкове зображення і завдасть на нього водяний знак.

Функція накладання водяного знаку

Отже, переходимо в файл functions.php і почнемо створювати функцію get_water():

function get_water($main_img_path, $load = FALSE) {
$main_img = getimagesize($main_img_path);
}

Дивіться, функція приймає лише два параметри (з яких один не обов’язковий):

$main_img_path – шлях до вихідного зображення, яке потрібно обробити;

$load – даний необов’язковий параметр приймає ім’я файлу, під яким повинно бути збережено нове оброблене зображення. Даний параметр відноситься до випадку, коли ми хочемо не вивести зображення на екран, а створити нове зображення з вихідного, з накладеним водяним знаком, і зберегти його в папці. Шлях до якої поставлено в конфігураційному файлі.

У цій функції насамперед необхідно отримати параметри вихідного зображення. Для цього ми використовуємо функцію getimagesize(), яка поверне нам масив, що містить різні параметри зображення (шлях до якого переданий їй параметром). Давайте роздрукуємо даний масив в браузері і подивимося, що у нас вийшло:

Нанесення водяних знаків на зображення засобами PHP

Тобто в комірках 0 і 1 міститься ширина і висота даного зображення. У комірці 2 одна з констант типу зображення (в нашому випадку значення 2 відповідає типу jpeg). Індекс 3 містить рядок зі значеннями ширини і висоти зображення width=»xxx» height=»yyy», яка може бути використана усередині тега img. Осередок mime – містить у собі відповідний MIME-тип зображення.

Далі весь код будемо вести всередині функції get_water(). Тепер необхідно перевірити, чи не повернула функція getimagesize() – FALSE. Якщо так, то виходимо з скрипта:

if(!$main_img) {
exit();
}

Далі відповідно до MIME-тип зображення створюємо на основі вихідного зображення — нове зображення в пам’яті. Для цього ми використовуємо оператор switch() і функції створення нового зображення на основі заданого відповідно до його типом:

switch($main_img[‘mime’]) {
case ‘image/jpeg’:
case ‘image/pjpeg’:
$img = imagecreatefromjpeg($main_img_path);
break;
case ‘image/png’:
case ‘image/x-png’:
$img = imagecreatefrompng($main_img_path);
break;
case ‘image/gif’:
$img = imagecreatefromgif($main_img_path);
break;
}

Зверніть увагу, що для MIME-типу ‘image/jpeg’, як і для ‘image/png’, потрібно враховувати і додаткові типи (‘image/pjpeg’ і ‘image/x-png’), які може нам повернути браузер Internet Explorer. Далі створюємо зображення в пам’яті заготовленого зображення під водяний знак:

if(file_exists(WM)) {
$water = imagecreatefrompng(WM);
}

Тут умовимося, що зображення водяного знака має бути тільки PNG, тому використовуємо відповідно функцію imagecreatefrompng(). Потім нам необхідно створити пусте зображення, точно такого ж розміру, як і вихідне. І перенести на нього спочатку вихідне зображення, а потім водяний знак. Для початку створюємо змінні для зберігання ширини та висоти майбутнього порожнього зображення:

$res_width = $main_img[0];
$res_height = $main_img[1];

Далі за допомогою функцій imagesx() і imagesy(), визначаємо ширину і висоту, відповідно, зображення водяного знака:

$water_width = imagesx($water);
$water_height = imagesy($water);

Потім створюємо порожній повнокольорове зображення з розмірами рівними розмірами вихідного зображення:

$res_img = imagecreatetruecolor($res_width,$res_height);

Тепер залишається перенести початкове зображення на тільки що створене:

imagecopyresampled($res_img,$img,0,0,0,0,
$res_width,$res_height,$main_img[0],$main_img[1]);

Для цього використовуємо функцію imagecopyresampled(), яка копіює і змінює, за необхідності, розміри зображення. Параметри передаються даної функції:

$res_img – дискриптор зображення на яке виконується копіювання (зображення приймач, то яке ми тільки що створили);

$img – копируемое зображення (джерело);

0 — x-координата зображення на яке виконується копіювання (точка на осі x в яку буде поміщений копируемое зображення);

0 — y-координата зображення на яке виконується копіювання (точка на осі y в яку буде поміщений копируемое зображення);

0 — x-координата зображення джерела (точка на осі x c якої буде виконано копіювання);

0 — y-координата зображення джерела (точка y c якої буде виконано копіювання);

$res_width – ширина ділянки зображення приймача, куди буде поміщений копируемое зображення;

$res_height — висота ділянки зображення приймача, куди буде поміщений копируемое зображення;

$main_img[0] – ширина ділянки копіюється зображення (в нашому випадку вказуємо повну ширину, так як нам потрібно скопіювати всі зображення, а не його частину);

$main_img[1] — висота ділянки копіюється зображення (в нашому випадку вказуємо повну висоту, так як нам потрібно скопіювати всі зображення, а не його частину);

Далі, нам необхідно перенести водяний знак:

imagecopy($res_img,$water,$res_width-$water_width,$res_height-$water_height,
0,0,$water_width,$water_height);

Для цього використовуємо функцію imagecopy. Параметри, що передаються функції:

$res_img – дискриптор зображення, на яке виконується копіювання (зображення приймач, то яке ми тільки що створили);

$water – дискриптор копіюється зображення;

$res_width-$water_width – координата по осі х, на зображенні приймачі, в яку буде поміщений копируемое зображення;

$res_height-$water_height — – координата по осі у, на зображенні приймачі, в яку буде поміщений копируемое зображення;

0 — x-координата зображення джерела (точка на осі x c якої буде виконано копіювання);

0 — y-координата зображення джерела (точка y c якої буде виконано копіювання);

$water_width — ширина ділянки копіюється зображення (в нашому випадку вказуємо повну ширину, так як нам потрібно скопіювати всі зображення, а не його частину);

$water_height — висота ділянки копіюється зображення (в нашому випадку вказуємо повну висоту, так як нам потрібно скопіювати всі зображення, а не його частину).

Далі необхідно залежно від того, що міститься в змінній $load, або вивести зображення на екран, або зберегти його в файл, що власне ми і зробимо:

if(!$load) {
header(“Content-Type:image/jpeg”);
imagejpeg($res_img,NULL,100);
}
else {
imagejpeg($res_img,DIR_IMG.$load,100);
}

Тобто, якщо ми не передамо при виклику функції параметр $load, значить, зображення буде виведено на екран. Якщо ж передати через параметр $load ім’я файлу, значить, нове зображення буде збережено під цим ім’ям. Тепер давайте відкриємо в браузері файл index.php і подивимося, як відпрацьовує наш скрипт:

Нанесення водяних знаків на зображення засобами PHP

Як Ви бачите, все працює відмінно. На всяк випадок приведу повний код даної функції:

function get_water($main_img_path, $load = FALSE) {
$main_img = getimagesize($main_img_path);
if(!$main_img) {
exit();
}
switch($main_img[‘mime’]) {
case ‘image/jpeg’:
case ‘image/pjpeg’:
$img = imagecreatefromjpeg($main_img_path);
break;
case ‘image/png’:
case ‘image/x-png’:
$img = imagecreatefrompng($main_img_path);
break;
case ‘image/gif’:
$img = imagecreatefromgif($main_img_path);
break;
}
if(file_exists(WM)) {
$water = imagecreatefrompng(WM);
}
$res_width = $main_img[0];
$res_height = $main_img[1];
$water_width = imagesx($water);
$water_height = imagesy($water);
$res_img = imagecreatetruecolor($res_width,$res_height);
imagecopyresampled($res_img,$img,0,0,0,0,$res_width,$res_height,
$main_img[0],$main_img[1]);
imagecopy($res_img,$water,$res_width-$water_width,$res_height-$water_height,
0,0,$water_width,$water_height);
if(!$load) {
header(“Content-Type:image/jpeg”);
imagejpeg($res_img,NULL,100);
}
else {
imagejpeg($res_img,DIR_IMG.$load,100);
}
}

Збереження обробленого зображення у файлі

Для того щоб не виводити на екран зображення з водяним знаком, а зберегти його в папці. Наприклад, це корисно, якщо виконується завантаження зображень на сервер через текстову форму. У цьому випадку зручно відразу ж наносити водяний знак на все зображення (якщо, звичайно, Ви не плануєте в майбутньому змінювати водяний знак). В цьому випадку можна створити найпростішу сторінку з формою для завантаження файлів і таким чином викликати нашу створену функцію (в моєму випадку це файл load.php):

Якщо запустити даний файл у браузері, то при завантаженні зображення на сервер, буде створюватися його копія з накладеним водяним знаком.

На цьому даний урок можна завершувати. Всього Вам доброго і вдалого кодування! І побачимося в наступних уроках!