Passed
Push — master ( 3f6c85...9c6499 )
by Jens
02:40
created

Image::loopThroughBodyAndCalculatePixels()   B

Complexity

Conditions 5
Paths 6

Size

Total Lines 32
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 5
eloc 16
nc 6
nop 8
dl 0
loc 32
rs 8.439
c 0
b 0
f 0

How to fix   Many Parameters   

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

1
<?php
2
/**
3
 * Image
4
 *
5
 * @Author : Jens Kooij
6
 * @Version: 1.0
7
 * @package: JNS MVC
8
 * @Licence: http://creativecommons.org/licenses/by-nc-nd/3.0/ Attribution-NonCommercial-NoDerivs 3.0 Unported
9
 */
10
11
namespace library\images {
12
	class Image
13
	{
14
		private $_imageResource;
15
16
		/**
17
		 * Load the a image resource into $this->_imageResource
18
		 * automagically :-)
19
		 *
20
		 * @param    resource | string | path
21
		 *
22
		 * @throws    \Exception
23
		 */
24
		public function loadImage($imageContainer)
25
		{
26
			if (is_resource($imageContainer) && get_resource_type($imageContainer) === 'gd') {
27
				$this->_imageResource = $imageContainer;
28
			} elseif (is_string($imageContainer) && file_exists($imageContainer)) {
29
				if ($this->getImageMimeType($imageContainer) == IMAGETYPE_BMP) {
30
					$this->_imageResource = $this->createImageFromBmp($imageContainer);
31
				} else {
32
					$imageContent = file_get_contents($imageContainer);
33
					$this->_imageResource = imagecreatefromstring($imageContent);
34
				}
35
			} elseif (is_string($imageContainer)) {
36
				$this->_imageResource = imagecreatefromstring($imageContainer);
37
			} else {
38
				throw new \Exception('Could not create image resource, accepted inputs are: "resource of type (gd)", path_to_image and "string". <br /><pre>' . var_export($imageContainer, true) . '</pre>');
39
			}
40
		}
41
42
		/**
43
		 * Saves the image to a file
44
		 *
45
		 * @param string $path
46
		 * @param int    $mimeTypeConstantValue
47
		 * @param int    $quality
48
		 * @param null   $imageResource If no resource is given, uses $this->_imageResource
49
		 *
50
		 * @return bool
51
		 * @throws \Exception
52
		 */
53
		public function saveImage($path, $mimeTypeConstantValue, $quality = 100, $imageResource = null)
54
		{
55
			if ($imageResource == null) {
56
				$imageResource = $this->getImageResource();
57
			}
58
59
			if ($mimeTypeConstantValue == IMAGETYPE_GIF) {
60
				return imagegif($imageResource, $path);
61
			} elseif ($mimeTypeConstantValue == IMAGETYPE_JPEG) {
62
				return imagejpeg($imageResource, $path, $quality);
63
			} elseif ($mimeTypeConstantValue == IMAGETYPE_PNG) {
64
				return imagepng($imageResource, $path, (intval($quality / 10) - 1));
65
			} else {
66
				throw new \Exception('Not a valid mimetypeconstant given see function documentation');
67
			}
68
		}
69
70
		/**
71
		 * Returns either the Mime-Type Constant value
72
		 * or the default extension for the detected mime-type;
73
		 *
74
		 * @see http://www.php.net/manual/en/function.image-type-to-mime-type.php
75
		 *
76
		 * @param string $imagePath
77
		 * @param bool   $getExtension
78
		 *
79
		 * @return bool|int|string
80
		 */
81
		public function getImageMimeType($imagePath, $getExtension = false)
82
		{
83
			if (function_exists('exif_imagetype')) {
84
				$exif = exif_imagetype($imagePath);
85
			} else {
86
				if ((list($width, $height, $type, $attr) = getimagesize($imagePath)) !== false) {
87
					$exif = $type;
88
				} else {
89
					$exif = false;
90
				}
91
			}
92
93
			return $getExtension ? image_type_to_extension($exif) : $exif;
94
		}
95
96
		/**
97
		 * Create Image resource from Bitmap
98
		 *
99
		 * @see       http://www.php.net/manual/en/function.imagecreatefromwbmp.php#86214
100
		 * @author    alexander at alexauto dot nl
101
		 *
102
		 * @param    string $pathToBitmapFile
103
		 *
104
		 * @return  resource
105
		 */
106
		public function createImageFromBmp($pathToBitmapFile)
107
		{
108
			$bitmapFileData = $this->getBitmapFileData($pathToBitmapFile);
109
110
			$temp = unpack("H*", $bitmapFileData);
111
			$hex = $temp[1];
112
			$header = substr($hex, 0, 108);
113
			list($width, $height) = $this->calculateWidthAndHeight($header);
114
115
			//    Define starting X and Y 
116
			$x = 0;
117
			$y = 1;
118
119
			$image = imagecreatetruecolor($width, $height);
120
121
			//    Grab the body from the image 
122
			$body = substr($hex, 108);
123
124
			//    Calculate if padding at the end-line is needed. Divided by two to keep overview. 1 byte = 2 HEX-chars
125
			$bodySize = (strlen($body) / 2);
126
			$headerSize = ($width * $height);
127
128
			//    Use end-line padding? Only when needed 
129
			$usePadding = ($bodySize > ($headerSize * 3) + 4);
130
			$this->loopThroughBodyAndCalculatePixels($bodySize, $x, $width, $usePadding, $y, $height, $body, $image);
131
132
			unset($body);
133
134
			return $image;
135
		}
136
137
		/**
138
		 * Returns the image resource
139
		 * @return resource
140
		 * @throws \Exception
141
		 */
142
		final public function getImageResource()
143
		{
144
			if (is_resource($this->_imageResource) && get_resource_type($this->_imageResource) === 'gd') {
145
				return $this->_imageResource;
146
			} else {
147
				throw new \Exception('Image resource is not set. Use $this->LoadImage to load an image into the resource');
148
			}
149
		}
150
151
		/**
152
		 * @param $pathToBitmapFile
153
		 *
154
		 * @return string
155
		 */
156
		private function getBitmapFileData($pathToBitmapFile)
157
		{
158
			$fileHandle = fopen($pathToBitmapFile, "rb");
159
			$bitmapFileData = fread($fileHandle, 10);
160
			while (!feof($fileHandle) && ($bitmapFileData <> "")) {
161
				$bitmapFileData .= fread($fileHandle, 1024);
162
			}
163
164
			return $bitmapFileData;
165
		}
166
167
		/**
168
		 * @param $header
169
		 *
170
		 * @return array
171
		 */
172
		private function calculateWidthAndHeight($header)
173
		{
174
			$width = null;
175
			$height = null;
176
177
			//    Structure: http://www.fastgraph.com/help/bmp_header_format.html
178
			if (substr($header, 0, 4) == "424d") {
179
				//    Cut it in parts of 2 bytes
180
				$header_parts = str_split($header, 2);
181
				//    Get the width        4 bytes
182
				$width = hexdec($header_parts[19] . $header_parts[18]);
183
				//    Get the height        4 bytes
184
				$height = hexdec($header_parts[23] . $header_parts[22]);
185
				//    Unset the header params
186
				unset($header_parts);
187
188
				return array($width, $height);
189
			}
190
191
			return array($width, $height);
192
		}
193
194
		/**
195
		 * Loop through the data in the body of the bitmap
196
		 * file and calculate each individual pixel based on the
197
		 * bytes
198
		 * @param $bodySize
199
		 * @param $x
200
		 * @param $width
201
		 * @param $usePadding
202
		 * @param $y
203
		 * @param $height
204
		 * @param $body
205
		 * @param $image
206
		 */
207
		private function loopThroughBodyAndCalculatePixels($bodySize, $x, $width, $usePadding, $y, $height, $body, $image)
208
		{
209
//    Using a for-loop with index-calculation instead of str_split to avoid large memory consumption
210
			//    Calculate the next DWORD-position in the body
211
			for ($i = 0; $i < $bodySize; $i += 3) {
212
				//    Calculate line-ending and padding
213
				if ($x >= $width) {
214
					//    If padding needed, ignore image-padding. Shift i to the ending of the current 32-bit-block
215
					if ($usePadding) {
216
						$i += $width % 4;
217
					}
218
					//    Reset horizontal position
219
					$x = 0;
220
					//    Raise the height-position (bottom-up)
221
					$y++;
222
					//    Reached the image-height? Break the for-loop
223
					if ($y > $height) {
224
						break;
225
					}
226
				}
227
				//    Calculation of the RGB-pixel (defined as BGR in image-data). Define $iPos as absolute position in the body
228
				$iPos = $i * 2;
229
				$r = hexdec($body[$iPos + 4] . $body[$iPos + 5]);
230
				$g = hexdec($body[$iPos + 2] . $body[$iPos + 3]);
231
				$b = hexdec($body[$iPos] . $body[$iPos + 1]);
232
				//    Calculate and draw the pixel
233
				$color = imagecolorallocate($image, $r, $g, $b);
234
				imagesetpixel($image, $x, $height - $y, $color);
235
				//    Raise the horizontal position
236
				$x++;
237
			}
238
		}
239
	}
240
}