95dcdb7a926ee5bfb3e216a0ddb14dcf4aaf6faa
[pixel-calc.git] / public_html / upload.php
1 <?php
2
3 function colourDiff($rgb1, $rgb2) {
4 $red1 = hexdec(substr($rgb1,0,2));
5 $green1 = hexdec(substr($rgb1,2,2));
6 $blue1 = hexdec(substr($rgb1,4,2));
7
8 $red2 = hexdec(substr($rgb2,0,2));
9 $green2 = hexdec(substr($rgb2,2,2));
10 $blue2 = hexdec(substr($rgb2,4,2));
11
12 return sqrt(pow($red1 - $red2, 2) + pow($green1 - $green2, 2) + pow($blue1 - $blue2, 2)) ;
13 }
14
15 function closest_colour($rgb, array $colours) {
16 $smallest_diff = 766;
17 $closest = 'none';
18
19 foreach($colours as $hex => $name)
20 {
21 if(colourDiff($rgb, $hex) < $smallest_diff) {
22 $smallest_diff = colourDiff($rgb, $hex);
23 $closest = $hex;
24 }
25 }
26
27 return $closest;
28 }
29
30 function array_to_table($array) {
31 $headings = $array[0];
32 unset($array[0]);
33 $output = '<table class="table"><tr>';
34
35 foreach($headings as $heading) {
36 $output .= '<th>' . $heading . '</th>';
37 }
38
39 $output .= '</tr>';
40
41 foreach($array as $row) {
42 $output .= '<tr>';
43
44 foreach($row as $column) {
45 $output .= '<td>' . $column . '</td>';
46 }
47
48 $output .= '</tr>';
49 }
50
51 $output .= '</table>';
52 return $output;
53 }
54
55 function image_to_array($image) {
56 $dimensions = getimagesize($image);
57 $image = imagecreatefrompng($image);
58 $array = array();
59
60 for($i=0; $i<$dimensions[1]; $i++) {
61 for($j=0; $j<$dimensions[0]; $j++) {
62 $rgb = imagecolorsforindex($image, imagecolorat($image, $j, $i));
63 $r = $rgb['red'];
64 $g = $rgb['green'];
65 $b = $rgb['blue'];
66 $a = $rgb['alpha'];
67
68 $hex =
69 str_pad(dechex($rgb['red']), 2, '0', STR_PAD_LEFT) .
70 str_pad(dechex($rgb['green']), 2, '0', STR_PAD_LEFT) .
71 str_pad(dechex($rgb['blue']), 2, '0', STR_PAD_LEFT);
72
73 if($a == 127) $hex = "NONE";
74
75 $array[$i][$j] = $hex;
76 }
77 }
78
79 return $array;
80 }
81
82 function array_to_sprite($array, $colourmap = NULL) {
83 $width = count($array[0]);
84 $height = count($array);
85 $output = "<table border='0' cellpadding='0' cellspacing='0'>";
86 for($i=0; $i<$height; $i++) {
87 $output .= '<tr>';
88 for($j=0; $j<$width; $j++) {
89 $hex = $colourmap ? $colourmap[$array[$i][$j]] : $array[$i][$j];
90 $output .= $array[$i][$j] !== 'NONE' ? "<td class='$hex' bgcolor='#$hex'></td>" : "<td bgcolor='#FFFFFF'></td>";
91 }
92
93 $output .= '</tr>';
94 }
95
96 $output .= '</table>';
97
98 return $output;
99 }
100
101 function generate_colourmap($array, $new_palette) {
102 $width = count($array[0]);
103 $height = count($array);
104 $colourMap = array('NONE' => 'NONE');
105
106 for($i=0; $i<$height; $i++) {
107 for($j=0; $j<$width; $j++) {
108 $colour = $array[$i][$j];
109 if(!isset($colourMap[$colour]))
110 $colourMap[$colour] = closest_colour($colour, $new_palette);
111 }
112 }
113
114 return $colourMap;
115 }
116
117 function count_pixels($array) {
118 $width = count($array[0]);
119 $height = count($array);
120 $count = 0;
121
122 for($i=0; $i<$height; $i++) {
123 for($j=0; $j<$width; $j++) {
124 if($array[$i][$j] !== 'NONE') $count++;
125 }
126 }
127
128 return $count;
129 }
130
131 function lumber_breakdown($cost_per_length, $wood_length, $wood_size, $num_blocks) {
132 $lengths_required = ceil($num_blocks*$wood_size/$wood_length);
133 $total_lumber_cost = $lengths_required * $cost_per_length;
134
135 return array_to_table(
136 array(
137 array(
138 'Num blocks',
139 'No of ' . $wood_length . 'm lengths required',
140 'Cost @ ' . $cost_per_length . ' per length'
141 ),
142 array(
143 $num_blocks,
144 $lengths_required,
145 $total_lumber_cost
146 )
147 )
148 );
149 }
150
151 function lumber_cost($cost_per_length, $wood_length, $wood_size, $num_blocks) {
152 $lengths_required = ceil($num_blocks*$wood_size/$wood_length);
153 return $lengths_required * $cost_per_length;
154 }
155
156 function colour_count($array, $colour_map = NULL) {
157 $width = count($array[0]);
158 $height = count($array);
159 $colour_count = array();
160
161 for($i=0; $i<$height; $i++) {
162 for($j=0; $j<$width; $j++) {
163 $colour = isset($colour_map[$array[$i][$j]]) ? $colour_map[$array[$i][$j]] : $array[$i][$j];
164 $colour_count[$colour] = isset($colour_count[$colour]) ? $colour_count[$colour]+1 : 1;
165 }
166 }
167
168 return $colour_count;
169 }
170
171 function colour_count_table($colour_count) {
172 $output = '<table class="table table-hover table-condensed"><tr><th>Colour</th><th>RGB</th><th>Num blocks</th></tr>';
173
174 foreach($colour_count as $colour => $count) {
175 //<tr class='colour-row' id='$colour'><td bgcolor='$colour'></td><td>$colour</td><td>$qty</td></tr>
176 if($colour != 'NONE')
177 $output .= '<tr class="colour-row" colour="' . $colour . '"><td bgcolor="' . $colour . '"></td><td>' . $colour . '</td><td>' . $count . '</td></tr>';
178 }
179
180 $output .= '</table>';
181
182 return $output;
183 }
184
185 function colour_breakdown($colour_count, $block_size, $can_coverage, $coats, $colour_names, $discount_matrix) {
186 $output = '<table class="table table-hover table-condensed"><tr><th>Colour</th><th>Name</th><th>Num cans</th><th>Can %</th><th>Full price</th><th>% Price</th></tr>';
187 $cost_per_can = $discount_matrix[0];
188 $total_cans = 0;
189
190 foreach($colour_count as $colour => $count) {
191 $total_cans += ceil($count * $block_size * $block_size / $can_coverage);
192 }
193
194 foreach($discount_matrix as $num_needed => $cost) {
195 if($total_cans <= $num_needed)
196 $cost_per_can = $cost;
197 }
198
199 foreach($colour_count as $colour => $count) {
200 $can_percent = $count * $block_size * $block_size * $coats / $can_coverage;
201 $num_needed = ceil($can_percent);
202 if(isset($colour_names[$colour]))
203 $output .= '<tr class="colour-row" colour="' . $colour . '"><td bgcolor="' . $colour . '"></td><td>' . $colour_names[$colour] . '</td><td>' . $num_needed . '</td><td>' . $can_percent . '</td><td>' . $cost_per_can*$num_needed . '</td><td>' . $can_percent * $cost_per_can . '</td></tr>';
204 }
205
206 $output .= '</table>';
207
208 return $output;
209 }
210
211 function spray_can_cost($colour_count, $block_size, $can_coverage, $coats, $discount_matrix, $percent_cost = FALSE) {
212 $cost_per_can = $discount_matrix[0];
213 $total_cans = 0;
214
215 foreach($colour_count as $colour => $count) {
216 $total_cans += $percent_cost ? $count * $block_size * $block_size * $coats / $can_coverage : ceil($count * $block_size * $block_size / $can_coverage);
217 }
218
219 foreach($discount_matrix as $num_needed => $cost) {
220 if($total_cans <= $num_needed)
221 $cost_per_can = $cost;
222 }
223
224 return $percent_cost ? end($discount_matrix)*$total_cans : $total_cans*$cost_per_can;
225 }
226
227 if(isset($_POST["submit"])) {
228 $ironlak_colours = array(
229 "532f18" => "Earth",
230 "753e00" => "Swiss",
231 "be854b" => "Mocha",
232 "e5ba83" => "Cuppa",
233 "f9e6c4" => "Irwin",
234 "fcf2e0" => "Fraser",
235
236 "be854b" => "Acacia",
237 "e5b53a" => "Tanami",
238 "f5d29c" => "Oat",
239 "ffdc01" => "Blaze",
240 "ffe04e" => "Pineapple Park",
241 "fffac4" => "Sorbet",
242
243 "de791b" => "Dieci Poes",
244 "f47d31" => "Halloween",
245 "f58427" => "Tues Afterburn",
246 "faae5d" => "Bowen",
247 "fdd29d" => "Smoothie",
248 "fcbc5e" => "Eureka",
249 "fed378" => "Butter",
250 "feefbb" => "Bondi",
251
252 "571b1e" => "Sirum Black-Red",
253 "8b0a02" => "Matador",
254 "d20d44" => "Soviet",
255 "e51a23" => "Autumn",
256 "cd4552" => "Isla Rose",
257 "f2797e" => "Guava",
258
259 "9c0159" => "Moberry",
260 "ea4498" => "Flirt",
261 "f38ab4" => "Potion",
262 "f6aec4" => "Delicious",
263 "f9cbd7" => "Crush",
264 "be76ad" => "Dusk",
265 "dd9ba5" => "Fantasia",
266 "fde6e0" => "Teegs Love",
267
268 "7e3e98" => "Pose Sushi",
269 "592049" => "Venom",
270 "78486a" => "Vino",
271 "c2739d" => "Furious",
272 "d4aed1" => "Gypsy",
273
274 "0a024e" => "Panther",
275 "62609a" => "Eggplant",
276 "7f76b7" => "Phantom",
277 "7d81be" => "Sofles Violence",
278 "8ba4d4" => "Granny",
279
280 "231f20" => "Augor's Blackout",
281 "00447b" => "Midnight",
282 "0068a9" => "Phat1's True Royal",
283 "0082c8" => "Smurf",
284 "00aeef" => "Enue's Bonggg!",
285 "78bde8" => "Torquay",
286 "89d3f4" => "Atmosphere",
287 "b9e1f7" => "Ozone",
288
289 "006b6e" => "Neverland",
290 "007b85" => "Hunter",
291 "00b5cb" => "Reef",
292 "2abdb1" => "Frazetta",
293 "8fd1c5" => "Linz Iceberg",
294 "c0e3da" => "Placid",
295 "70c6a2" => "Jante",
296
297 "006224" => "Huey",
298 "3f9537" => "Field",
299 "6cb43f" => "Cameleon",
300 "b3d78b" => "Reals Sublime",
301 "e6eebc" => "Whizbang",
302
303 "514e25" => "Askew's Olivia",
304 "677717" => "Guacamole",
305 "9ea615" => "Gangrene",
306 "ac9601" => "Banos Asbestos",
307 "d4d110" => "Kryptonite",
308 "f4eb0a" => "Keen",
309 "fcf26f" => "Nitro",
310
311 "434c3d" => "Lazy Grey",
312 "a0a1a5" => "Battleship",
313 "c5c6c8" => "Washington",
314 "f0f1f2" => "Smoulder",
315
316 "a29161" => "Gold",
317 "a8a9ad" => "Bright Chrome",
318
319 "ffffff" => "Whitest Possible",
320 "000000" => "Blackest Possible"
321 );
322
323 $discount_matrix = array(
324 0 => 6.36, //120+ cans
325 199 => 6.6, //60-199 cans
326 59 => 6.76, //36-59 cans
327 35 => 7, //12-35 cans
328 11 => 7.16, //6-11 cans
329 5 => 7.95 // 0-5 cans
330 );
331
332 $pixel_array = image_to_array($_FILES["fileToUpload"]["tmp_name"]);
333 $sprite_width_px = count($pixel_array[0]);
334 $sprite_height_px = count($pixel_array);
335 $colour_map = generate_colourmap($pixel_array, $ironlak_colours);
336 $original_sprite = array_to_sprite($pixel_array);
337 $ironlak_sprite = array_to_sprite($pixel_array, $colour_map);
338
339 $lumber_breakdown = lumber_breakdown($_POST['wood_cost'], $_POST['wood_length'], $_POST['wood_size'], count_pixels($pixel_array));
340
341 $original_colour_table = colour_count_table(colour_count($pixel_array));
342 $ironlak_colour_table = colour_count_table(colour_count($pixel_array, $colour_map));
343
344 $spray_can_breakdown = colour_breakdown(colour_count($pixel_array, $colour_map), $_POST['wood_size'], 2.2, 3, $ironlak_colours, $discount_matrix);
345
346 $cost_of_cans = spray_can_cost(colour_count($pixel_array, $colour_map), $_POST['wood_size'], 2.2, 3, $discount_matrix);
347 $value_of_can_used = spray_can_cost(colour_count($pixel_array, $colour_map), $_POST['wood_size'], 2.2, 3, $discount_matrix, TRUE);
348 // echo $original_sprite;
349 // echo $original_colour_table;
350 //
351 // echo $ironlak_sprite;
352 // echo $ironlak_colour_table;
353 //
354 // echo $lumber_breakdown;
355 // echo $spray_can_breakdown;
356
357 require_once('./breakdown.html');
358 }
359 ?>