Наложение маски на картинку средствами php GD

Наложение маски на картинку средствами php GDВ этой статье я хочу показать как можно наложить маску на изображение. После наложения маски исходное изображение будет обрезано по форме маски. Маской является картинки любого допустимого формата(jpg, jpeg, png, gif). Для создания пустых мест используется белый цвет RGB(255, 255, 255).

Весь код я оформил в функцию для удобства использования. Код функции подробно прокомментирован, а также приведен пример использования:

/**
* Наложение маски на картинку
* @var string $image - пусть до картинки. Поддерживаются форматы: jpg, jpeg, png, gif
* @var string $mask - путь до маски. Поддерживаются форматы: jpg, jpeg, png, gif
*
* @return image - возвращает изображение
*/
function imagemask($image, $mask){
    // получаем формат картинки
    $arrImg = explode(".", $image);
    $format = (end($arrImg) == 'jpg') ? 'jpeg': end($arrImg);
    $imgFunc = "imagecreatefrom" . $format; //определение функции для расширения файла
    // получаем формат маски
    $arrMask = explode(".", $mask);
    $format = (end($arrMask) == 'jpg') ? 'jpeg': end($arrMask);
    $maskFunc = "imagecreatefrom" . $format; //определение функции для расширения файла
    
    $image = $imgFunc($image); // загружаем картинку
    $mask = $maskFunc($mask); // загружаем маску
    $width =  imagesx($image); // определяем ширину картинки
    $height = imagesy($image); // определяем высоту картинки
    $img = imagecreatetruecolor($width, $height); // создаем холст для будущей картинки
    $transColor = imagecolorallocate($img, 0, 0, 0); // определяем прозрачный цвет для картинки. Черный
    imagecolortransparent($img,$transColor); // задаем прозрачность для картинки
    // перебираем картинку по пикселю
    for($posX = 0; $posX < $width; $posX++){ 
        for($posY = 0; $posY < $height; $posY++){
            $colorIndex = imagecolorat($image, $posX, $posY); // получаем индекс цвета пикселя в координате $posX, $posY для картинки
            $colorImage = imagecolorsforindex($image, $colorIndex); // получаем цвет по его индексу в формате RGB
            $colorIndex = imagecolorat($mask, $posX, $posY); // получаем индекс цвета пикселя в координате $posX, $posY для маски
            $maskColor = imagecolorsforindex($mask, $colorIndex); // получаем цвет по его индексу в формате RGB
            // если в точке $posX, $posY цвет маски не белый, то наносим на холст пиксель с нужным цветом
            if (!($maskColor['red'] == 255 && $maskColor['green'] == 255 && $maskColor['blue'] == 255)){
                $colorIndex = imagecolorallocate($img, $colorImage['red'], $colorImage['green'], $colorImage['blue']); // получаем цвет для пикселя
                imagesetpixel($img, $posX, $posY, $colorIndex); // рисуем пиксель
            } 
        }
    }
    return $img; // вернем изображение
}

И пример использования функции:

// пример использования
header('Content-type: image/png'); // заголовок для браузера
$img = imagemask('test.jpg' , 'mask.png'); // накладываем маску
imagepng($img); // выводим картинку в браузере
imagedestroy($img); // чистим память
Рассказать друзьям:


Наложение маски на картинку средствами php GD: 4 комментария

  1. Почему-то маска работает, но на самой картинке (под видимой частью маски) тоже пропадает черный цвет. Не пойму в чем проблема:(

    1. Здравствуйте, это происходит потому, что в примере для наглядности прозрачным цветов объявлен именно черный. Чтобы этой проблемы избежать можно задать другой цвет, например, RGB(1, 2, 3) — маловероятно что такой встретится на изображении.
      Измените строку:
      $transColor = imagecolorallocate($img, 0, 0, 0);
      на такую:
      $transColor = imagecolorallocate($img, 1, 2, 3);

      И при отрисовке изображения допишите в условие:
      условие else:

      // если в точке $posX, $posY цвет маски не белый, то наносим на холст пиксель с нужным цветом
      if (!($maskColor[‘red’] == 255 && $maskColor[‘green’] == 255 && $maskColor[‘blue’] == 255)){
      $colorIndex = imagecolorallocate($img, $colorImage[‘red’], $colorImage[‘green’], $colorImage[‘blue’]); // получаем цвет для пикселя
      imagesetpixel($img, $posX, $posY, $colorIndex); // рисуем пиксель
      }else{
      imagesetpixel($img, $posX, $posY, $transColor); // рисуем пиксель
      }

      После этого дополнения должно все хорошо работать.

  2. Автор очень крут. Спасибо, сэкономили мне кучу времени.
    Кстати, пример без модификаций нормально работает с прозрачным png (не вдавался в подробности, почему так получилось).

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

*