4

I am using Intervention Image image manipulation library this library in a project and I am stuck on adding watermark image all over the source image.

Is it possible to repeat the watermark image on all over the source image like in the following example?

stock-photo-79576145-old-room

I try the following code, but it doesn't work for me.

$thumbnail = $manager->make($name);
$watermark = $manager->make($watermarkSource);
$x = 0;

while ($x < $thumbnail->width()) {
    $y = 0;

    while($y < $thumbnail->height()) {
        $thumbnail->insert($watermarkSource, 'top-left', $x, $y);
        $y += $watermark->height();
    }

    $x += $watermark->width();
}

$thumbnail->save($name, 80);
Shifrin
  • 154
  • 1
  • 11

2 Answers2

8

I've just solved this problem via Intervention Image library using it in Laravel Framework. So here's code snippet.

public function watermarkPhoto(String $originalFilePath,String $filePath2Save ){

    $watermark_path='photos/watermark.png';
    if(\File::exists($watermark_path)){

        $watermarkImg=Image::make($watermark_path);
        $img=Image::make($originalFilePath);
        $wmarkWidth=$watermarkImg->width();
        $wmarkHeight=$watermarkImg->height();

        $imgWidth=$img->width();
        $imgHeight=$img->height();

        $x=0;
        $y=0;
        while($y<=$imgHeight){
            $img->insert($watermark_path,'top-left',$x,$y);
            $x+=$wmarkWidth;
            if($x>=$imgWidth){
                $x=0;
                $y+=$wmarkHeight;
            }
        }
        $img->save($filePath2Save);

        $watermarkImg->destroy();
        $img->destroy(); //  to free memory in case you have a lot of images to be processed
    }
    return $filePath2Save;
}

If you use PHP version prior to 7 remove String type declaration from function arguments. just make it

    public function watermarkPhoto($originalFilePath, $filePath2Save ){....}

Also if you are not using Laravel Framework and you don't have File class included just remove redundand check from function.

      if(\File::exists($watermark_path))

So the simplest framework-agnostic function would be:

function watermarkPhoto($originalFilePath, $filePath2Save ){

        $watermark_path='photos/watermark.png';
        $watermarkImg=Image::make($watermark_path);
        $img=Image::make($originalFilePath);
        $wmarkWidth=$watermarkImg->width();
        $wmarkHeight=$watermarkImg->height();

        $imgWidth=$img->width();
        $imgHeight=$img->height();

        $x=0;
        $y=0;
        while($y<=$imgHeight){
            $img->insert($watermark_path,'top-left',$x,$y);
            $x+=$wmarkWidth;
            if($x>=$imgWidth){
                $x=0;
                $y+=$wmarkHeight;
            }
        }
        $img->save($filePath2Save);

        $watermarkImg->destroy();
        $img->destroy();

    return $filePath2Save;
}

Also you need watermark image in png format with transparent background.

Mikhail.root
  • 764
  • 9
  • 18
  • 2
    Thank you very much for your reply, My code was working just fine, when I was tested there was a problem with the "imagick" driver and later I found it's just working fine. Still, I'm using that in my project. – Shifrin Dec 07 '16 at 06:50
1

I'm just adding one thing added to your accepted answer when you try your code and the above-accepted code, the watermark on the images will be very close together and close together with what I tried. like this

enter image description here

So if you want the watermarks like what you want, you need to modify the code with plus numbers on wmarkheight and wmarkwidth like this:

while ($x < $imgWidth) {
            $y = 0;

            while($y < $imgHeight) {
                $imgFileCollection->insert($watermark, 'top-left', $x, $y);
                $y += $wmarkHeight+30;
            }

            $x += $wmarkWidth+40;
        }

this line of code is important:

$y += $wmarkHeight+30;
$x += $wmarkWidth+40;

and you will get the result like that below:

enter image description here

Mohsin Khan
  • 89
  • 1
  • 7