Passed
Push — master ( ec0ca6...f04b64 )
by Anthony
02:55
created

Resize::getOptimalCrop()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 17
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 17
rs 9.4285
cc 2
eloc 10
nc 2
nop 2
1
<?php
2
3
   # ========================================================================#
4
   #
5
   #  Author:    Jarrod Oberto
6
   #  Version:	 1.0
7
   #  Date:      17-Jan-10
8
   #  Purpose:   Resizes and saves image
9
   #  Requires : Requires PHP5, GD library.
10
   # ========================================================================#
11
	namespace core\images;
12
13
		Class Resize
14
		{
15
			// *** Class variables
16
			private $image;
17
			private $width;
18
			private $height;
19
			private $imageResized;
20
21
			/**
22
			 * Resize constructor.
23
			 * @param null|string $fileName
24
			 */
25
			public function __construct($fileName)
26
			{
27
				// *** Open up the file
28
				$this->image = $this->openImage($fileName);
29
30
				// *** Get width and height
31
				$this->width  = imagesx($this->image);
32
				$this->height = imagesy($this->image);
33
			}
34
35
			## --------------------------------------------------------
36
			/**
37
			 * @param null|string $file
38
			 * @return bool|resource
39
			 */
40
			private function openImage($file)
41
			{
42
				// *** Get extension
43
				$extension = strtolower(strrchr($file, '.'));
44
45
				switch ($extension)
46
				{
47
					case '.jpg':
48
					case '.jpeg':
49
						$img = @imagecreatefromjpeg($file);
50
						break;
51
					case '.gif':
52
						$img = @imagecreatefromgif($file);
53
						break;
54
					case '.png':
55
						$img = @imagecreatefrompng($file);
56
						break;
57
					default:
58
						$img = false;
59
						break;
60
				}
61
				return $img;
62
			}
63
64
			## --------------------------------------------------------
65
66
			public function resizeImage($newWidth, $newHeight, $option = "auto")
67
			{
68
				// *** Get optimal width and height - based on $option
69
				$optionArray = $this->getDimensions($newWidth, $newHeight, $option);
70
71
				$optimalWidth  = $optionArray['optimalWidth'];
72
				$optimalHeight = $optionArray['optimalHeight'];
73
74
75
				// *** Resample - create image canvas of x, y size
76
				$this->imageResized = imagecreatetruecolor($optimalWidth, $optimalHeight);
77
				imagecopyresampled($this->imageResized, $this->image, 0, 0, 0, 0, $optimalWidth, $optimalHeight, $this->width, $this->height);
78
79
80
				// *** if option is 'crop', then crop too
81
				if ($option == 'crop') {
82
					$this->crop($optimalWidth, $optimalHeight, $newWidth, $newHeight);
83
				}
84
			}
85
86
			## --------------------------------------------------------
87
			/**
88
			 * @param $newWidth
89
			 * @param $newHeight
90
			 * @param string $option
91
			 * @return array
92
			 */
93
			private function getDimensions($newWidth, $newHeight, $option)
94
			{
95
96
			   switch ($option)
97
				{
98
					case 'exact':
99
						$optimalWidth = $newWidth;
100
						$optimalHeight = $newHeight;
101
						break;
102
					case 'portrait':
103
						$optimalWidth = $this->getSizeByFixedHeight($newHeight);
104
						$optimalHeight = $newHeight;
105
						break;
106
					case 'landscape':
107
						$optimalWidth = $newWidth;
108
						$optimalHeight = $this->getSizeByFixedWidth($newWidth);
109
						break;
110 View Code Duplication
					case 'auto':
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
111
						$optionArray = $this->getSizeByAuto($newWidth, $newHeight);
112
						$optimalWidth = $optionArray['optimalWidth'];
113
						$optimalHeight = $optionArray['optimalHeight'];
114
						break;
115 View Code Duplication
					case 'crop':
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
116
						$optionArray = $this->getOptimalCrop($newWidth, $newHeight);
117
						$optimalWidth = $optionArray['optimalWidth'];
118
						$optimalHeight = $optionArray['optimalHeight'];
119
						break;
120
				   default:
121
					   $optimalWidth = "";
122
					   $optimalHeight = "";
123
					   break;
124
				}
125
				return array('optimalWidth' => $optimalWidth, 'optimalHeight' => $optimalHeight);
126
			}
127
128
			## --------------------------------------------------------
129
130
			private function getSizeByFixedHeight($newHeight)
131
			{
132
				$ratio = $this->width / $this->height;
133
				$newWidth = $newHeight * $ratio;
134
				return $newWidth;
135
			}
136
137
			private function getSizeByFixedWidth($newWidth)
138
			{
139
				$ratio = $this->height / $this->width;
140
				$newHeight = $newWidth * $ratio;
141
				return $newHeight;
142
			}
143
144
			private function getSizeByAuto($newWidth, $newHeight)
145
			{
146
				if ($this->height < $this->width) {
147
								// *** Image to be resized is wider (landscape)
148
				{
149
					$optimalWidth = $newWidth;
150
				}
151
					$optimalHeight = $this->getSizeByFixedWidth($newWidth);
152
				} elseif ($this->height > $this->width) {
153
								// *** Image to be resized is taller (portrait)
154
				{
155
					$optimalWidth = $this->getSizeByFixedHeight($newHeight);
156
				}
157
					$optimalHeight = $newHeight;
158
				} else
159
				// *** Image to be resizerd is a square
160
				{
161
					if ($newHeight < $newWidth) {
162
						$optimalWidth = $newWidth;
163
						$optimalHeight = $this->getSizeByFixedWidth($newWidth);
164
					} else if ($newHeight > $newWidth) {
165
						$optimalWidth = $this->getSizeByFixedHeight($newHeight);
166
						$optimalHeight = $newHeight;
167
					} else {
168
						// *** Sqaure being resized to a square
169
						$optimalWidth = $newWidth;
170
						$optimalHeight = $newHeight;
171
					}
172
				}
173
174
				return array('optimalWidth' => $optimalWidth, 'optimalHeight' => $optimalHeight);
175
			}
176
177
			## --------------------------------------------------------
178
179
			private function getOptimalCrop($newWidth, $newHeight)
180
			{
181
182
				$heightRatio = $this->height / $newHeight;
183
				$widthRatio  = $this->width / $newWidth;
184
185
				if ($heightRatio < $widthRatio) {
186
					$optimalRatio = $heightRatio;
187
				} else {
188
					$optimalRatio = $widthRatio;
189
				}
190
191
				$optimalHeight = $this->height / $optimalRatio;
192
				$optimalWidth  = $this->width / $optimalRatio;
193
194
				return array('optimalWidth' => $optimalWidth, 'optimalHeight' => $optimalHeight);
195
			}
196
197
			## --------------------------------------------------------
198
199
			private function crop($optimalWidth, $optimalHeight, $newWidth, $newHeight)
200
			{
201
				// *** Find center - this will be used for the crop
202
				$cropStartX = ($optimalWidth / 2) - ($newWidth / 2);
203
				$cropStartY = ($optimalHeight / 2) - ($newHeight / 2);
204
205
				$crop = $this->imageResized;
206
207
				// *** Now crop from center to exact requested size
208
				$this->imageResized = imagecreatetruecolor($newWidth, $newHeight);
209
				imagecopyresampled($this->imageResized, $crop, 0, 0, $cropStartX, $cropStartY, $newWidth, $newHeight, $newWidth, $newHeight);
210
			}
211
212
			## --------------------------------------------------------
213
			/**
214
			 * @param string $savePath
215
			 * @param string $imageQuality
216
			 */
217
			public function saveImage($savePath, $imageQuality = "100")
218
			{
219
				// *** Get extension
220
				$extension = strrchr($savePath, '.');
221
	   			$extension = strtolower($extension);
222
223
				switch ($extension)
224
				{
225
					case '.jpg':
226
					case '.jpeg':
227
						if (imagetypes() & IMG_JPG) {
228
							imagejpeg($this->imageResized, $savePath, $imageQuality);
229
						}
230
						break;
231
232
					case '.gif':
233
						if (imagetypes() & IMG_GIF) {
234
							imagegif($this->imageResized, $savePath);
235
						}
236
						break;
237
238
					case '.png':
239
						// *** Scale quality from 0-100 to 0-9
240
						$scaleQuality = round(($imageQuality / 100) * 9);
241
242
						// *** Invert quality setting as 0 is best, not 9
243
						$invertScaleQuality = 9 - $scaleQuality;
244
245
						if (imagetypes() & IMG_PNG) {
246
							 imagepng($this->imageResized, $savePath, $invertScaleQuality);
247
						}
248
						break;
249
250
					// ... etc
251
252
					default:
253
						// *** No extension - No save.
254
						break;
255
				}
256
257
				imagedestroy($this->imageResized);
258
			}
259
260
261
			## --------------------------------------------------------
262
263
		}