Skip to content

Commit 107e623

Browse files
committed
Fix bug in imagick driver's CropModifier
See: #1426
1 parent 70bbb17 commit 107e623

File tree

1 file changed

+22
-21
lines changed

1 file changed

+22
-21
lines changed

src/Drivers/Imagick/Modifiers/CropModifier.php

+22-21
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
namespace Intervention\Image\Drivers\Imagick\Modifiers;
66

77
use Imagick;
8-
use Intervention\Image\Drivers\Imagick\Driver;
98
use Intervention\Image\Interfaces\ImageInterface;
109
use Intervention\Image\Interfaces\SpecializedInterface;
1110
use Intervention\Image\Modifiers\CropModifier as GenericCropModifier;
@@ -14,20 +13,30 @@ class CropModifier extends GenericCropModifier implements SpecializedInterface
1413
{
1514
public function apply(ImageInterface $image): ImageInterface
1615
{
17-
$crop = $this->crop($image);
16+
// decode background color
1817
$background = $this->driver()->colorProcessor($image->colorspace())->colorToNative(
1918
$this->driver()->handleInput($this->background)
2019
);
2120

2221
// create empty container imagick to rebuild core
2322
$imagick = new Imagick();
23+
24+
// save resolution to add it later
2425
$resolution = $image->resolution()->perInch();
2526

27+
// define position of the image on the new canvas
28+
$crop = $this->crop($image);
29+
$position = [
30+
($crop->pivot()->x() + $this->offset_x) * -1,
31+
($crop->pivot()->y() + $this->offset_y) * -1,
32+
];
33+
2634
foreach ($image as $frame) {
2735
// create new frame canvas with modifiers background
2836
$canvas = new Imagick();
2937
$canvas->newImage($crop->width(), $crop->height(), $background, 'png');
3038
$canvas->setImageResolution($resolution->x(), $resolution->y());
39+
$canvas->setImageAlphaChannel(Imagick::ALPHACHANNEL_SET); // or ALPHACHANNEL_ACTIVATE?
3140
3241
// set animation details
3342
if ($image->isAnimated()) {
@@ -36,31 +45,23 @@ public function apply(ImageInterface $image): ImageInterface
3645
$canvas->setImageDispose($frame->native()->getImageDispose());
3746
}
3847

39-
// place original frame content onto the empty colored frame canvas
40-
$canvas->compositeImage(
41-
$frame->native(),
42-
Imagick::COMPOSITE_DEFAULT,
43-
($crop->pivot()->x() + $this->offset_x) * -1,
44-
($crop->pivot()->y() + $this->offset_y) * -1,
45-
);
48+
// Make the entire rectangle at the position of the original image
49+
// transparent so that we can later place the original on top.
50+
// This preserves the transparency of the original and shows
51+
// the background color of the modifier in the other areas
52+
$clear = new Imagick();
53+
$clear->newImage($frame->native()->getImageWidth(), $frame->native()->getImageHeight(), 'black');
54+
$canvas->compositeImage($clear, Imagick::COMPOSITE_DSTOUT, ...$position);
4655

47-
// copy alpha channel if available
48-
if ($frame->native()->getImageAlphaChannel()) {
49-
$canvas->compositeImage(
50-
$frame->native(),
51-
version_compare(Driver::version(), '7.0.0', '>=') ?
52-
Imagick::COMPOSITE_COPYOPACITY :
53-
Imagick::COMPOSITE_DSTIN,
54-
($crop->pivot()->x() + $this->offset_x) * -1,
55-
($crop->pivot()->y() + $this->offset_y) * -1,
56-
);
57-
}
56+
// place original frame content onto the empty colored frame canvas
57+
// with the transparent rectangle
58+
$canvas->compositeImage($frame->native(), Imagick::COMPOSITE_DEFAULT, ...$position);
5859

5960
// add newly built frame to container imagick
6061
$imagick->addImage($canvas);
6162
}
6263

63-
// replace imagick
64+
// replace imagick in the original image
6465
$image->core()->setNative($imagick);
6566

6667
return $image;

0 commit comments

Comments
 (0)