5
5
namespace Intervention \Image \Drivers \Imagick \Modifiers ;
6
6
7
7
use Imagick ;
8
- use Intervention \Image \Drivers \Imagick \Driver ;
9
8
use Intervention \Image \Interfaces \ImageInterface ;
10
9
use Intervention \Image \Interfaces \SpecializedInterface ;
11
10
use Intervention \Image \Modifiers \CropModifier as GenericCropModifier ;
@@ -14,20 +13,30 @@ class CropModifier extends GenericCropModifier implements SpecializedInterface
14
13
{
15
14
public function apply (ImageInterface $ image ): ImageInterface
16
15
{
17
- $ crop = $ this -> crop ( $ image );
16
+ // decode background color
18
17
$ background = $ this ->driver ()->colorProcessor ($ image ->colorspace ())->colorToNative (
19
18
$ this ->driver ()->handleInput ($ this ->background )
20
19
);
21
20
22
21
// create empty container imagick to rebuild core
23
22
$ imagick = new Imagick ();
23
+
24
+ // save resolution to add it later
24
25
$ resolution = $ image ->resolution ()->perInch ();
25
26
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
+
26
34
foreach ($ image as $ frame ) {
27
35
// create new frame canvas with modifiers background
28
36
$ canvas = new Imagick ();
29
37
$ canvas ->newImage ($ crop ->width (), $ crop ->height (), $ background , 'png ' );
30
38
$ canvas ->setImageResolution ($ resolution ->x (), $ resolution ->y ());
39
+ $ canvas ->setImageAlphaChannel (Imagick::ALPHACHANNEL_SET ); // or ALPHACHANNEL_ACTIVATE?
31
40
32
41
// set animation details
33
42
if ($ image ->isAnimated ()) {
@@ -36,31 +45,23 @@ public function apply(ImageInterface $image): ImageInterface
36
45
$ canvas ->setImageDispose ($ frame ->native ()->getImageDispose ());
37
46
}
38
47
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 );
46
55
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 );
58
59
59
60
// add newly built frame to container imagick
60
61
$ imagick ->addImage ($ canvas );
61
62
}
62
63
63
- // replace imagick
64
+ // replace imagick in the original image
64
65
$ image ->core ()->setNative ($ imagick );
65
66
66
67
return $ image ;
0 commit comments