Размещаем полупрозрачный логотип поверх большого изображения (watermark) средствами php.

Я написал небольшой class для такого дела.

Результат работы скрипта:

Метки: watermark, image, php

php

class image { ######################## watermark var $watermark = array( 'white' => 'w_87px.png', // белое изображение 'dark' => 'd_87px.png',// темное изображение (не обязательно) 'x' => -22, // позиция изображения по горизонтали (если позиция с минусом то отсчет от правого края) 'y' => 22, // позиция изображения по вертикали (если позиция с минусом то отсчет от нижнего края) ); var $src_dir = 'src/'; var $res_dir = 'res/'; var $sign_dir = 'mark/'; var $alpha_level = 90; var $jpeg_quality = 90; // качество результирующего jpg файла function _sign_image($src_file, $file = 'res.jpg') { ## получаем основное изображение $main_img_obj = imagecreatefromjpeg($this->src_dir.$src_file); ## получаем размер изображения размещяемого поверх (белое и темное изображение должны быть одинакового размера) $wmimg = GetImageSize($this->sign_dir.$this->watermark['white']); ## star mark $this->alpha_level /= 100; // получаем % прозрачности $main_img_obj_w = imagesx( $main_img_obj ); // размер большого изображения ширина $main_img_obj_h = imagesy( $main_img_obj ); // размер большого изображения высота $watermark_img_obj_w = $wmimg[0]; // размер water mark изображения ширина $watermark_img_obj_h = $wmimg[1]; // размер water mark изображения высота $tx = $this->watermark['x']; // смещение по x $ty = $this->watermark['y']; // смещение по y ## определяем координаты места в котором будет размещяться water mark $main_img_obj_min_x = $tx >= 0 ? $tx : ($main_img_obj_w + $tx - $watermark_img_obj_w); $main_img_obj_max_x = $tx >= 0 ? ($tx + $watermark_img_obj_w) : ($main_img_obj_w - intval($tx)); $main_img_obj_min_y = $ty >= 0 ? $ty : ($main_img_obj_h + $ty - $watermark_img_obj_h);//$main_img_obj_h - $watermark_img_obj_h + $ty; $main_img_obj_max_y = $ty >= 0 ? ($ty + $watermark_img_obj_h) : ($main_img_obj_h - intval($ty));//$main_img_obj_h + $ty; ## создаем пустое изображение $return_img = imagecreatetruecolor( $main_img_obj_w, $main_img_obj_h ); ## копируем в пустое изображение оригинал imagecopy($return_img, $main_img_obj, 0, 0, 0, 0, $main_img_obj_w, $main_img_obj_h); ## если у нас используется два типа логотипа белое и темное, то определяем цвет в размещаемом в блоке ## если темное изображение отсутствует то просто используем одно изображение if(!empty($this->watermark['dark'])){ $c = 0; $ko = 20; for($k = 0; $k < $ko; $k++ ){ $xx = rand($main_img_obj_min_x, $main_img_obj_max_x); $yy = rand($main_img_obj_min_y, $main_img_obj_max_y); $rgb = @ImageColorAt($main_img_obj, $xx, $yy); $r = ($rgb >> 16) & 0xFF; $g = ($rgb >> 8) & 0xFF; $b = $rgb & 0xFF; $cm = intval(($r + $g + $b) / 3); $c = $c + $cm; } $c = intval($c / $ko); ## если усредненный цвет в этом блоке более светлый то размещаем светлый логотип если темный соответственно темное изображение $watermark_img_obj = $c < 127 ? imagecreatefrompng($this->sign_dir.$this->watermark['white']) : imagecreatefrompng($this->sign_dir.$this->watermark['dark']); } else { $watermark_img_obj = imagecreatefrompng($this->sign_dir.$this->watermark['white']); } ## пробегаем основное изображение for( $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 ) ); ## во всех точках в месте размещения water mark пересчитываем новый цвет 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 ) ); $watermark_alpha = round(((127 - $watermark_rbg['alpha'] ) / 127), 2); $watermark_alpha = $watermark_alpha * $this->alpha_level; $avg_red = $this->_get_color( $main_rgb['red'], $watermark_rbg['red'], $watermark_alpha ); $avg_green = $this->_get_color( $main_rgb['green'], $watermark_rbg['green'], $watermark_alpha ); $avg_blue = $this->_get_color( $main_rgb['blue'], $watermark_rbg['blue'], $watermark_alpha ); $return_color = $this->_get_image_color( $return_img, $avg_red, $avg_green, $avg_blue ); } else { $return_color = imagecolorat( $main_img_obj, $x, $y ); } imagesetpixel( $return_img, $x, $y, $return_color ); } } imagejpeg($return_img, $this->res_dir.$file, $this->jpeg_quality); } ## function _get_color( $color_a, $color_b, $alpha_level) { return round((($color_a * ( 1 - $alpha_level ) ) + ( $color_b * $alpha_level ))); } ## определяем новый цвет точки 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); } } $new = new Image(); $new->_sign_image(rand(1,7).'.jpg');

Прикрепленные материалы

Куплю производственную землю. Купить участок дорохово - участок в сергиевом пассаде.. Дома экопан. Мы находимся в новгородской области. Хочешь хорошую работу - подготовка водителей. Аренда автомобилей с водителем.