Image icon indicating copy to clipboard operation
Image copied to clipboard

Discussion: merge (feature/function) not work as expected

Open Bogdaan opened this issue 8 years ago • 4 comments

I have some issues with merge method after image resize (scale resize). For example: If you images is too large 2000x1000 and you need preserve aspect ratio - then you resize images with scaleResize. Typycal task for merge: place watermark over image.

But you can not use both methods together:

Case A) reseze + merge:

        echo $srcImg
            ->scaleResize($width, $height)
            ->merge($watermarkImg,
                $srcWidth - $watermarkW,
                $srcHeight - $watermarkH
            )
            ->html();

Result: watermark on transparent background (INVISIBLE) depends on aspect ratio.

Case B) merge + resize:

        echo $srcImg
            ->merge($watermarkImg,
                $srcWidth - $watermarkW,
                $srcHeight - $watermarkH
            )
            ->scaleResize($width, $height)
            ->html();

Result: watermark is visible but too small (resized with image).

My solution (compare ratio before place):

        // need this sizes
        $width = 1000;
        $height = 300;

        $watermarkPath = /tmp/watermark.png';
        $watermarkImg = AppImage::open($watermarkPath);

        $watermarkW = 157;
        $watermarkH = 50;

        $srcImg = AppImage::open('/tmp/test.jpg');

        $srcWidth = $srcImg->width();
        $srcHeight = $srcImg->height();

        $aspectRatio = $srcWidth / $srcHeight;
        $needRatio = $width / $height;

        $resultXOffset = $width - $watermarkW;
        $resultYOffset = $height - $watermarkH;

        if ($needRatio < $aspectRatio) {
            $realHeight = $width / $aspectRatio;
            $resultYOffset = $realHeight - $watermarkH + ($height - $realHeight) / 2;

        } else if ($needRatio > $aspectRatio) {
            $realWidth = $height * $aspectRatio;
            $resultXOffset = $realWidth - $watermarkW + ($width - $realWidth) / 2;
        }

        echo $srcImg
            ->scaleResize($width, $height)
            ->merge($watermarkImg, $resultXOffset, $resultYOffset)
            ->html();

So, now it is impossible place watermark on top/left/bottom of images?

Bogdaan avatar Mar 28 '16 17:03 Bogdaan

I guess your problem is to get the image width and height after resize after all, right?

Gregwar avatar Mar 28 '16 23:03 Gregwar

@Gregwar yes resize works as expected, but after resize merge place image on empty place (not image).

aspectRatio ( > 1 )

-------------
|   empty   |
|   image   |
|   empty   |
-------------

or aspectRatio ( < 1 )

---------------------------
|   empty  image empty    |
---------------------------

Bogdaan avatar Mar 29 '16 07:03 Bogdaan

For example other library have a method

Intervention\Image\Image insert(mixed $source, [string $position, [integer $x, integer $y]])

with position parameter:

  • top-left (default)
  • top
  • top-right
  • left
  • center
  • right
  • bottom-left
  • bottom
  • bottom-right

And works as expected. May be similar method would be useful?

Bogdaan avatar Mar 29 '16 07:03 Bogdaan

This is indeed a good idea to add this If you do a PR i'll review it

Gregwar avatar Apr 03 '16 17:04 Gregwar