@@ -60,7 +60,6 @@ final class Image
6060 */
6161 public static function resize (\Imagick $ source , int $ boxWidth , int $ boxHeight , array $ options = []) : \Imagick
6262 {
63- $ boxSizes = [['width ' => $ boxWidth , 'height ' => $ boxHeight ]];
6463 $ options += self ::DEFAULT_OPTIONS ;
6564
6665 //algorithm inspired from http://today.java.net/pub/a/today/2007/04/03/perils-of-image-getscaledinstance.html
@@ -103,143 +102,130 @@ public static function resize(\Imagick $source, int $boxWidth, int $boxHeight, a
103102 ['$options["maxHeight"] was not an int ' ]
104103 );
105104
106- foreach ($ boxSizes as $ boxSizeKey => $ boxSize ) {
107- if (!isset ($ boxSize ['width ' ]) || !is_int ($ boxSize ['width ' ])) {
108- throw new InvalidArgumentException ('a width in a $boxSizes value was not an int ' );
109- }
110-
111- if (!isset ($ boxSize ['height ' ]) || !is_int ($ boxSize ['height ' ])) {
112- throw new InvalidArgumentException ('a height in a $boxSizes value was not an int ' );
113- }
114105
115- if ($ boxSize [ ' width ' ] > $ maxWidth || $ boxSize [ ' width ' ] <= 0 ) {
116- throw new InvalidArgumentException ('a $boxSizes width was not between 0 and $options["maxWidth"] ' );
117- }
106+ if ($ boxWidth > $ maxWidth || $ boxWidth <= 0 ) {
107+ throw new InvalidArgumentException ('a $boxSizes width was not between 0 and $options["maxWidth"] ' );
108+ }
118109
119- if ($ boxSize ['height ' ] > $ maxHeight || $ boxSize ['height ' ] <= 0 ) {
120- throw new InvalidArgumentException ('a $boxSizes height was not between 0 and $options["maxHeight"] ' );
121- }
110+ if ($ boxHeight > $ maxHeight || $ boxHeight <= 0 ) {
111+ throw new InvalidArgumentException ('a $boxSizes height was not between 0 and $options["maxHeight"] ' );
122112 }
123113
124114 $ results = [];
125115 $ cloneCache = [];
126- foreach ($ boxSizes as $ boxSizeKey => $ boxSize ) {
127- $ boxWidth = $ boxSize ['width ' ];
128- $ boxHeight = $ boxSize ['height ' ];
129-
130- $ clone = clone $ source ;
131-
132- self ::rotateImage ($ clone );
133-
134- $ width = $ clone ->getImageWidth ();
135- $ height = $ clone ->getImageHeight ();
136-
137- //ratio over 1 is horizontal, under 1 is vertical
138- $ boxRatio = $ boxWidth / $ boxHeight ;
139- //height should be positive since I didnt find a way you could get zero into imagick
140- $ originalRatio = $ width / $ height ;
116+ $ clone = clone $ source ;
141117
142- $ targetWidth = null ;
143- $ targetHeight = null ;
144- $ targetX = null ;
145- $ targetY = null ;
146- if ($ width < $ boxWidth && $ height < $ boxHeight && !$ upsize ) {
147- $ targetWidth = $ width ;
148- $ targetHeight = $ height ;
149- $ targetX = ($ boxWidth - $ width ) / 2 ;
150- $ targetY = ($ boxHeight - $ height ) / 2 ;
118+ self ::rotateImage ($ clone );
119+
120+ $ width = $ clone ->getImageWidth ();
121+ $ height = $ clone ->getImageHeight ();
122+
123+ //ratio over 1 is horizontal, under 1 is vertical
124+ $ boxRatio = $ boxWidth / $ boxHeight ;
125+ //height should be positive since I didnt find a way you could get zero into imagick
126+ $ originalRatio = $ width / $ height ;
127+
128+ $ targetWidth = null ;
129+ $ targetHeight = null ;
130+ $ targetX = null ;
131+ $ targetY = null ;
132+ if ($ width < $ boxWidth && $ height < $ boxHeight && !$ upsize ) {
133+ $ targetWidth = $ width ;
134+ $ targetHeight = $ height ;
135+ $ targetX = ($ boxWidth - $ width ) / 2 ;
136+ $ targetY = ($ boxHeight - $ height ) / 2 ;
137+ } else {
138+ //if box is more vertical than original
139+ if ($ boxRatio < $ originalRatio ) {
140+ $ targetWidth = $ boxWidth ;
141+ $ targetHeight = (int )((double )$ boxWidth / $ originalRatio );
142+ $ targetX = 0 ;
143+ $ targetY = ($ boxHeight - $ targetHeight ) / 2 ;
151144 } else {
152- //if box is more vertical than original
153- if ($ boxRatio < $ originalRatio ) {
154- $ targetWidth = $ boxWidth ;
155- $ targetHeight = (int )((double )$ boxWidth / $ originalRatio );
156- $ targetX = 0 ;
157- $ targetY = ($ boxHeight - $ targetHeight ) / 2 ;
158- } else {
159- $ targetWidth = (int )((double )$ boxHeight * $ originalRatio );
160- $ targetHeight = $ boxHeight ;
161- $ targetX = ($ boxWidth - $ targetWidth ) / 2 ;
162- $ targetY = 0 ;
163- }
145+ $ targetWidth = (int )((double )$ boxHeight * $ originalRatio );
146+ $ targetHeight = $ boxHeight ;
147+ $ targetX = ($ boxWidth - $ targetWidth ) / 2 ;
148+ $ targetY = 0 ;
164149 }
150+ }
165151
166- //do iterative downsize by halfs (2x2 binning is a common name) on dimensions that are bigger than target
167- //width and height
168- while (true ) {
169- $ widthReduced = false ;
170- $ widthIsHalf = false ;
171- if ($ width > $ targetWidth ) {
172- $ width = (int )($ width / 2 );
173- $ widthReduced = true ;
174- $ widthIsHalf = true ;
175- if ($ width < $ targetWidth ) {
176- $ width = $ targetWidth ;
177- $ widthIsHalf = false ;
178- }
179- }
180-
181- $ heightReduced = false ;
182- $ heightIsHalf = false ;
183- if ($ height > $ targetHeight ) {
184- $ height = (int )($ height / 2 );
185- $ heightReduced = true ;
186- $ heightIsHalf = true ;
187- if ($ height < $ targetHeight ) {
188- $ height = $ targetHeight ;
189- $ heightIsHalf = false ;
190- }
191- }
192-
193- if (!$ widthReduced && !$ heightReduced ) {
194- break ;
152+ //do iterative downsize by halfs (2x2 binning is a common name) on dimensions that are bigger than target
153+ //width and height
154+ while (true ) {
155+ $ widthReduced = false ;
156+ $ widthIsHalf = false ;
157+ if ($ width > $ targetWidth ) {
158+ $ width = (int )($ width / 2 );
159+ $ widthReduced = true ;
160+ $ widthIsHalf = true ;
161+ if ($ width < $ targetWidth ) {
162+ $ width = $ targetWidth ;
163+ $ widthIsHalf = false ;
195164 }
165+ }
196166
197- $ cacheKey = "{$ width }x {$ height }" ;
198- if (isset ($ cloneCache [$ cacheKey ])) {
199- $ clone = clone $ cloneCache [$ cacheKey ];
200- continue ;
167+ $ heightReduced = false ;
168+ $ heightIsHalf = false ;
169+ if ($ height > $ targetHeight ) {
170+ $ height = (int )($ height / 2 );
171+ $ heightReduced = true ;
172+ $ heightIsHalf = true ;
173+ if ($ height < $ targetHeight ) {
174+ $ height = $ targetHeight ;
175+ $ heightIsHalf = false ;
201176 }
177+ }
202178
203- if ($ clone ->resizeImage ($ width , $ height , \Imagick::FILTER_BOX , 1.0 ) !== true ) {
204- //cumbersome to test
205- throw new \Exception ('Imagick::resizeImage() did not return true ' );//@codeCoverageIgnore
206- }
179+ if (!$ widthReduced && !$ heightReduced ) {
180+ break ;
181+ }
207182
208- if ($ widthIsHalf && $ heightIsHalf ) {
209- $ cloneCache [$ cacheKey ] = clone $ clone ;
210- }
183+ $ cacheKey = "{$ width }x {$ height }" ;
184+ if (isset ($ cloneCache [$ cacheKey ])) {
185+ $ clone = clone $ cloneCache [$ cacheKey ];
186+ continue ;
211187 }
212188
213- if ($ upsize && ($ width < $ targetWidth || $ height < $ targetHeight )) {
214- if ($ clone ->resizeImage ($ targetWidth , $ targetHeight , \Imagick::FILTER_CUBIC , 1.0 , $ bestfit ) !== true ) {
215- //cumbersome to test
216- throw new \Exception ('Imagick::resizeImage() did not return true ' );//@codeCoverageIgnore
217- }
189+ if ($ clone ->resizeImage ($ width , $ height , \Imagick::FILTER_BOX , 1.0 ) !== true ) {
190+ //cumbersome to test
191+ throw new \Exception ('Imagick::resizeImage() did not return true ' );//@codeCoverageIgnore
218192 }
219193
220- if ($ clone ->getImageHeight () === $ boxHeight && $ clone ->getImageWidth () === $ boxWidth ) {
221- $ results [$ boxSizeKey ] = $ clone ;
222- continue ;
194+ if ($ widthIsHalf && $ heightIsHalf ) {
195+ $ cloneCache [$ cacheKey ] = clone $ clone ;
223196 }
197+ }
224198
225- //put image in box
226- $ canvas = self ::getBackgroundCanvas ($ source , $ color , $ blurBackground , $ blurValue , $ boxWidth , $ boxHeight );
227- if ($ canvas ->compositeImage ($ clone , \Imagick::COMPOSITE_ATOP , $ targetX , $ targetY ) !== true ) {
199+ if ($ upsize && ($ width < $ targetWidth || $ height < $ targetHeight )) {
200+ if ($ clone ->resizeImage ($ targetWidth , $ targetHeight , \Imagick::FILTER_CUBIC , 1.0 , $ bestfit ) !== true ) {
228201 //cumbersome to test
229- throw new \Exception ('Imagick::compositeImage () did not return true ' );//@codeCoverageIgnore
202+ throw new \Exception ('Imagick::resizeImage () did not return true ' );//@codeCoverageIgnore
230203 }
204+ }
231205
232- //reason we are not supporting the options in self::write() here is because format, and strip headers are
233- //only relevant once written Imagick::stripImage() doesnt even have an effect until written
234- //also the user can just call that function with the resultant $canvas
235- $ results [$ boxSizeKey ] = $ canvas ;
206+ if ($ clone ->getImageHeight () === $ boxHeight && $ clone ->getImageWidth () === $ boxWidth ) {
207+ foreach ($ cloneCache as $ cachedClone ) {
208+ $ cachedClone ->destroy ();
209+ }
210+
211+ return $ clone ;
236212 }
237213
214+ //put image in box
215+ $ canvas = self ::getBackgroundCanvas ($ source , $ color , $ blurBackground , $ blurValue , $ boxWidth , $ boxHeight );
216+ if ($ canvas ->compositeImage ($ clone , \Imagick::COMPOSITE_ATOP , $ targetX , $ targetY ) !== true ) {
217+ //cumbersome to test
218+ throw new \Exception ('Imagick::compositeImage() did not return true ' );//@codeCoverageIgnore
219+ }
220+
221+ //reason we are not supporting the options in self::write() here is because format, and strip headers are
222+ //only relevant once written Imagick::stripImage() doesnt even have an effect until written
223+ //also the user can just call that function with the resultant $canvas
238224 foreach ($ cloneCache as $ clone ) {
239225 $ clone ->destroy ();
240226 }
241227
242- return $ results [ 0 ] ;
228+ return $ canvas ;
243229 }
244230
245231 /**
0 commit comments