]> git.llucax.com Git - personal/website.git/blob - source/blog/posts/2011/04/bandlogos-cli.php
Move eventxx submodule to the repo subdir
[personal/website.git] / source / blog / posts / 2011 / 04 / bandlogos-cli.php
1 <?php
2
3 $USER = 'llucax';
4 $PERIOD = '7day'; // 7day, 3moth, 6month, 12month, overall
5 // black, gray, blue, red, orange, turquoise, trans, white
6 // or array(R, G, B) for an arbitrary color
7 $STYLE = array(246,146,30);
8 $N_ARTISTS = 10;
9 $COLUMNS = 1; // 1 or 2
10 $API_KEY = "db109383394640f2b5e174b4514f0014";
11 $GRAY_VALUE = 239;
12 $MARGIN_SIDE = 4; // Side margin (in px)
13 $MARGIN_TOP = 4; // Between the first logo and top
14 $SEPERATION = 5; // Separation between logos
15 $LOGOS_DIR = 'logos';
16
17 /**
18  * @param string Name of the artist
19  * @return Artist Infos of the artist
20  */
21 function get_artist_image($name)
22 {
23         global $LOGOS_DIR;
24         foreach (glob($LOGOS_DIR . '/' . $name . '.*') as $file) {
25                 $info = pathinfo($file);
26                 $ext = strtolower($info['extension']);
27                 if ($ext == 'gif')
28                         return imagecreatefromgif($file);
29                 if ($ext == 'jpeg' || $ext == 'jpg')
30                         return imagecreatefromjpeg($file);
31                 if ($ext == 'png')
32                         return imagecreatefrompng($file);
33         }
34         return null;
35 }
36
37 /**
38  * Invert color from an image ressource.
39  *
40  * @param ressource $image Image
41  * "param string $color ID of a filter
42  */
43 function img_apply_filter($image, $color)
44 {
45         if ($color == 'black')
46                 img_add_invert_filter($image);
47         elseif ($color == 'gray')
48                 img_add_gray_filter($image);
49         elseif ($color == 'blue')
50                 img_add_color_filter($image, array(40,79,148));
51         elseif ($color == 'red')
52                 img_add_color_filter($image, array(214,17,2));
53         elseif ($color == 'orange')
54                 img_add_color_filter($image, array(222,54,0));
55         elseif ($color == 'turquoise')
56                 img_add_color_filter($image, array(69,168,196));
57         elseif ($color == 'trans')
58                 img_add_trans_filter($image);
59         elseif ($color == 'white')
60                 return;
61         elseif (is_array($color))
62                 img_add_color_filter($image, $color);
63         else
64                 throw new Exception("Unknown filter.");
65 }
66
67
68 /**
69  * Invert color from an image ressource.
70  *
71  * @param ressource $image Image
72  */
73 function img_add_invert_filter($image)
74 {
75         $width = imagesx($image);
76         $height = imagesy($image);
77
78         for ($x = 0; $x < $width; $x++) {
79                 for ($y = 0; $y < $height; $y++) {
80                         $oldCol = img_get_color_array($image,$x,$y);
81                         $newColor = img_get_invert_color($oldCol);
82                         imagesetpixel($image, $x, $y,
83                                 img_get_col_ref($image,$newColor));
84                 }
85         }
86 }
87
88 /**
89  * Make the image darker and make the background transparent.
90  *
91  * @param ressource $image Image
92  */
93 function img_add_trans_filter($image) {
94         global $GRAY_VALUE;
95         $height = imagesy($image);
96         // Set gray as the transparent color
97         $ref = imagecolorresolve($image, $GRAY_VALUE, $GRAY_VALUE, $GRAY_VALUE);
98         imagecolortransparent($image, $ref);
99
100         for ($x = 0; $x < $width; $x++) {
101                 for ($y = 0; $y < $height; $y++) {
102                         $oldCol = img_get_color_array($image, $x, $y);
103                         $newColor = img_get_darker_color($oldCol, $GRAY_VALUE);
104                         imagesetpixel($image, $x, $y,
105                                 img_get_col_ref($image,$newColor,$ref));
106                 }
107         }
108 }
109
110 /**
111  * Make the image darker.
112  * - White pixel become darker.
113  * - Black pixel stay the same.
114  *
115  * @param ressource $image Image
116  */
117 function img_add_gray_filter($image)
118 {
119         global $GRAY_VALUE;
120
121         $width = imagesx($image);
122         $height = imagesy($image);
123
124         for ($x = 0; $x < $width; $x++) {
125                 for ($y = 0; $y < $height; $y++) {
126                         $oldCol = img_get_color_array($image, $x, $y);
127                         $newColor = img_get_darker_color($oldCol, $GRAY_VALUE);
128                         imagesetpixel($image, $x, $y,
129                                 img_get_Col_Ref($image,$newColor));
130                 }
131         }
132 }
133
134 /**
135  * Replace the black color and dark tone to the given color.
136  *
137  * @param ressource $image Image
138  * @param array $color Color that will replace black
139  */
140 function img_add_color_filter($image, array $color)
141 {
142         global $GRAY_VALUE;
143
144         $width = imagesx($image);
145         $height = imagesy($image);
146
147         $ref = imagecolorresolve($image, $GRAY_VALUE, $GRAY_VALUE, $GRAY_VALUE);
148         imagecolortransparent($image,$ref);
149
150         for ($x = 0; $x < $width; $x++) {
151                 for ($y = 0; $y < $height; $y++) {
152                         $oldCol = img_get_color_array($image, $x, $y);
153                         $newColor = img_change_dark_to_spec_color(
154                                 img_get_darker_color($oldCol, $GRAY_VALUE),$color);
155                         imagesetpixel($image, $x, $y,
156                                 img_get_col_ref($image, $newColor, $ref));
157                 }
158         }
159 }
160
161 ////// Color basic util. //////
162
163 /**
164  * Simple shortcut to get a color ref for the current image.
165  *
166  * @param ressource $image Image
167  * @param array $newColor RGB color array of the color added
168  * @param int $transRef If set should  reference the transparent color id
169  * @return Return the ref id to the new color (can only be use for the given image)
170  */
171 function img_get_col_ref($image, array $newColor, $transRef=NULL)
172 {
173         global $GRAY_VALUE;
174
175         $ref = imagecolorresolve($image, $newColor[0], $newColor[1],
176                 $newColor[2]);
177         if ($transRef && (array_sum($newColor) >= ($GRAY_VALUE - 15) * 3))
178                 $ref = $transRef; // imagecolortransparent($image,$ref);
179         return $ref;
180 }
181
182 /**
183  * @param ressource $image Image
184  * @param int $x X position
185  * @param int $y Y position
186  * @return Get the RGB array for a given position
187  */
188 function img_get_color_array($image, $x, $y)
189 {
190         $pos = imagecolorat($image, $x, $y);
191         $f = imagecolorsforindex($image, $pos);
192         $col = NULL;
193
194         if (count($f) == 3) {
195                 $col = array($f['red'], $f['green'], $f['blue']);
196         }
197         else {
198                 $gst = $f['red'] * 0.15 + $f['green'] * 0.5 + $f['blue'] * 0.35;
199                 $col = array($gst, $gst, $gst);
200         }
201
202         return $col;
203 }
204
205 ////// Color modifications pattern //////
206
207 /**
208  * @param array $color RGB color
209  * @return the RGB opposite
210  */
211 function img_get_invert_color(array $color)
212 {
213         return array(255 - $color[0], 255 - $color[1], 255 - $color[2]);
214 }
215
216 /**
217  * @param array $color RGB color
218  * @param int $gray Gray Level (0-255) Lower is darker
219  * @return a RGB color darker than the original
220  */
221 function img_get_Darker_color(array $color, $gray)
222 {
223         $color[0] -= $color[0] / 255 * (255 - $gray);
224
225         // Base on the assumption the color are grayscale
226         $color[2] = $color[1] = $color[0];
227
228         return $color;
229 }
230
231  /**
232  * 
233  */
234 function img_change_dark_to_spec_color(array $color, array $newColor)
235 {
236         global $GRAY_VALUE;
237
238         $sum = array_sum($color);
239
240         if ($sum < ($GRAY_VALUE - 15) * 3) {
241                 $color[0] += $newColor[0] * (255 - $color[0]) / 255;
242                 $color[1] += $newColor[1] * (255 - $color[1]) / 255;
243                 $color[2] += $newColor[2] * (255 - $color[2]) / 255;
244         }
245         return $color;
246 }
247
248 /**
249  * Output the image with the logos of each artist
250  */
251 function show_one_col($artists, $artists_no, $color, $width)
252 {
253         global $MARGIN_TOP, $MARGIN_SIDE, $SEPERATION;
254
255         $totalHeight=0;
256         $listImageRessources = array();
257
258         foreach ($artists as $name) {
259                 if (count($listImageRessources) == $artists_no)
260                         break;
261
262                 $image = get_artist_image($name);
263
264                 if ($image !== null) {
265                         $totalHeight += imagesy($image) + $SEPERATION;
266                         array_push($listImageRessources, $image);
267                 }
268         }
269         $totalHeight += $MARGIN_TOP;
270
271         $container = imagecreatetruecolor($width, $totalHeight);
272
273         // Some colors needed
274         $colWhite = imagecolorallocate($container, 255, 255, 255);
275
276         // Background color
277         imagefilledrectangle($container, 0, 0, $width, $totalHeight, $colWhite);
278
279         $expectWidth = $width - (2 * $MARGIN_SIDE);
280         $currentHeight = $MARGIN_TOP;
281         foreach ($listImageRessources as $image) {
282                 $widthImg = imagesx($image);
283                 imagecopymerge($container, $image,
284                         $MARGIN_SIDE + ($widthImg < $expectWidth ?
285                                         ($expectWidth - $widthImg) * 0.5 : 0),
286                         $currentHeight, 0, 0, imagesx($image), imagesy($image),
287                         100);
288                 $currentHeight += imagesy($image) + $SEPERATION;
289         }
290
291         img_apply_filter($container, $color);
292
293         imagepng($container);
294 }
295
296 /**
297  * Output the image with the logos of each artist
298  */
299 function show_two_col($artists, $artists_no, $color, $width)
300 {
301         global $MARGIN_TOP, $MARGIN_SIDE, $SEPERATION;
302
303         if (count($artists) == 0)
304                 throw new Exception("Missing some informations (artists).");
305
306         $totalHeight = array($MARGIN_TOP, $MARGIN_TOP);
307         $listImageRessources = array(array(), array());
308
309         $forcedWidth = ($width / 2) - ($SEPERATION / 2);
310
311         foreach ($artists as $name) {
312                 if (count($listImageRessources[0]) +
313                                 count($listImageRessources[1]) == $artists_no)
314                         break;
315
316                 $image = get_artist_image($name);
317
318                 if ($image !== null) {
319                         $i = 0;
320                         if ($totalHeight[1] < $totalHeight[0])
321                                 $i = 1;
322
323                         $x = imagesx($image);
324                         $y = imagesy($image);
325                         $newHeight = floor(($y * $forcedWidth) / $x);
326
327                         $totalHeight[$i] += $newHeight + $SEPERATION;
328                         array_push($listImageRessources[$i], $image);
329                 }
330         }
331
332         $container = imagecreatetruecolor($width, max($totalHeight));
333
334         // Some colors needed
335         $colWhite = imagecolorallocate($container, 255, 255, 255);
336
337         // Background color
338         imagefilledrectangle($container, 0, 0, $width, max($totalHeight), $colWhite);
339
340         $currentHeight = array($MARGIN_TOP, $MARGIN_TOP);
341         for ($l = 0; $l < count($listImageRessources); $l++) {
342                 $list = $listImageRessources[$l];
343
344                 foreach ($list as $image) {
345                         $x = imagesx($image);
346                         $y = imagesy($image);
347
348                         $newHeight = floor(($y * $forcedWidth) / $x);
349
350                         $resized = imagecreatetruecolor($forcedWidth, $newHeight);                              
351                         imagecopyresampled($resized, $image, 0, 0, 0, 0,
352                                 $forcedWidth, $newHeight, $x, $y);
353
354                         imagecopymerge($container, $resized,
355                                 ($forcedWidth + $SEPERATION) * $l,
356                                 $currentHeight[$l], 0, 0,
357                                 $forcedWidth, $newHeight, 100);
358
359                         $currentHeight[$l] += $newHeight + $SEPERATION;
360                 }
361         }
362
363         img_apply_filter($container, $color);
364
365         imagepng($container);
366 }
367
368 /**
369  * Optain the list of Top artists from a user
370  * @param string $accountName Unique name
371  * @param int $nbArtists Number of artists to list
372  */
373 function get_list_top_artists($username, $type='overall', $nbArtists=0)
374 {
375         global $API_KEY;
376         if (strlen($username) == 0 || strlen($username) > 15)
377                 throw new Exception("Invalid username.");
378
379         $content = file_get_contents("http://ws.audioscrobbler.com/2.0/" .
380                 "?method=user.gettopartists" .
381                 "&user=" . $username.
382                 "&period=" . $type.
383                 "&api_key=" . $API_KEY);
384         $lines = explode("\n", $content);
385         if (count($lines) == 0)
386                 throw new Exception("Feed is empty.");
387
388         $artists = array();
389         $noartist = 0;
390         foreach ($lines as $line) {
391                 // Skip useless line
392                 if (strrpos($line, "<url>http://www.last.fm/music/") ===
393                                 false)
394                         continue;
395
396                 // Extract the encode name from the url
397                 preg_match("(http://www.last.fm/music/([^<]+))", $line,
398                         $proper);
399                 array_push($artists, $proper[1]);
400                 $noartist++;
401
402                 if ($noartist == $nbArtists) // Stop when max
403                         break;
404         }
405
406         if (count($artists) == 0)
407                 throw new Exception("No Artist found. Invalid feed??");
408
409         return $artists;
410 }
411
412 $artists = get_list_top_artists($USER, $PERIOD);
413
414 if (count($artists) > 0)
415         if ($COLUMNS == 1)
416                 show_one_col($artists, $N_ARTISTS, $STYLE, 168);
417         elseif ($COLUMNS == 2)
418                 show_two_col($artists, $N_ARTISTS, $STYLE, 300);
419         else
420                 throw new Exception("Invalid number of columns.");
421 else
422         throw new Exception("No artist found.");
423
424 ?>