1: <?php
2:
3: 4: 5: 6: 7: 8: 9: 10: 11:
12:
13: namespace Pry\Image;
14:
15: 16: 17: 18: 19: 20: 21: 22:
23: class Image
24: {
25:
26: const IMG_GIF = 1;
27: const IMG_JPG = 2;
28: const IMG_PNG = 3;
29: const IMG_SWF = 4;
30: const IMG_PSD = 5;
31: const IMG_BMP = 6;
32: const IMG_TIF = 7;
33:
34: 35: 36: 37:
38: protected $width;
39:
40: 41: 42: 43:
44: protected $height;
45:
46: 47: 48: 49: 50: 51:
52: protected $type;
53:
54: 55: 56: 57:
58: protected $mime;
59:
60: 61: 62: 63:
64: protected $source;
65:
66: 67: 68: 69:
70: protected $font;
71:
72: 73: 74: 75:
76: protected $couleur;
77:
78: 79: 80: 81:
82: protected $infoImage;
83:
84: 85: 86: 87:
88: protected $poids;
89: private $copie;
90:
91: 92: 93: 94:
95: private $logo;
96:
97: 98: 99: 100:
101: private $widthL;
102:
103: 104: 105: 106:
107: private $heightL;
108:
109: 110: 111: 112:
113: private $typeL;
114:
115: 116: 117: 118: 119: 120:
121: public function __construct($img, $w = null, $h = null)
122: {
123: if (!empty($img) && file_exists($img))
124: {
125: if (!is_readable($img))
126: {
127: throw new Image_Exception('Le fichier n\'est pas ouvert en lecture');
128: exit;
129: }
130: $info = getimagesize($img);
131: $this->width = $info[0];
132: $this->height = $info[1];
133: $this->type = $info[2];
134: $this->mime = $info['mime'];
135: $this->copie = null;
136: $this->source = $this->createFromType($img);
137: if ($this->source == false)
138: {
139: throw new Exception('Format d\'image non supporté. Seul les formats JPG,PNG ou GIF sont admis');
140: exit;
141: }
142: $this->couleur = imagecolorallocate($this->source, 187, 3, 33);
143: $this->poids = filesize($img);
144: $this->infoImage = array();
145: $this->infoImage['extension'] = strchr($img, '.');
146: $this->infoImage['extension'] = substr($this->infoImage['extension'], 1);
147: $this->infoImage['extension'] = strtolower($this->infoImage['extension']);
148: }
149: else
150: {
151: 152: 153: 154:
155: if ($w > 0 && $h > 0)
156: {
157: $width = intval($w);
158: $height = intval($h);
159: $this->source = imagecreatetruecolor($width, $height);
160: $this->width = $width;
161: $this->height = $height;
162: $this->type = null;
163: }
164: else
165: {
166: throw new Exception('Si aucune image source n\'est fournie la taille est obligatoire');
167: exit;
168: }
169: }
170: }
171:
172: 173: 174: 175: 176:
177: public function getInfo()
178: {
179: $this->infoImage['width'] = $this->width;
180: $this->infoImage['height'] = $this->height;
181: $this->infoImage['mime'] = $this->mime;
182: $this->infoImage['poids'] = round($this->poids / 1024, 2);
183:
184: return $this->infoImage;
185: }
186:
187: 188: 189: 190: 191:
192: public function addLogo($logo)
193: {
194: if (!file_exists($logo))
195: throw new Exception('Le logo ne semble pas exister');
196:
197: $this->logo = new Image($logo);
198:
199: $tailleLogo = $this->logo->getInfo();
200: $this->widthL = $tailleLogo['width'];
201: $this->heightL = $tailleLogo['height'];
202: }
203:
204: 205: 206: 207: 208: 209: 210:
211: public function mergeLogo($pos = 'bd', $opacite = 75)
212: {
213: if ($pos == 'hg')
214: {
215: $posX = 0;
216: $posY = 0;
217: }
218: elseif ($pos == 'hd')
219: {
220: $posX = ($this->width - $this->widthL);
221: $posY = 0;
222: }
223: elseif ($pos == 'bg')
224: {
225: $posX = 0;
226: $posY = ($this->height - $this->heightL);
227: }
228: elseif ($pos == 'bd')
229: {
230: $posX = ($this->width - $this->widthL);
231: $posY = ($this->height - $this->heightL);
232: }
233: elseif ($pos == 'ct')
234: {
235: $posX = (($this->width / 2) - ($this->widthL / 2));
236: $posY = (($this->height / 2) - ($this->heightL / 2));
237: }
238:
239: if (imagecopymerge($this->source, $this->logo->getSource(), $posX, $posY, 0, 0, $this->widthL, $this->heightL, $opacite))
240: return true;
241: else
242: return false;
243: }
244:
245: 246: 247: 248: 249: 250:
251: protected function createFromType($img)
252: {
253: if ($this->type == self::IMG_GIF)
254: {
255: $crea = imagecreatefromgif($img);
256: imagealphablending($crea, TRUE);
257: }
258: elseif ($this->type == self::IMG_JPG)
259: {
260: $crea = imagecreatefromjpeg($img);
261: }
262: elseif ($this->type == self::IMG_PNG)
263: {
264: $crea = imagecreatefrompng($img);
265: imagealphablending($crea, true);
266: imagesavealpha($crea, true);
267: }
268: else
269: $crea = false;
270:
271: return $crea;
272: }
273:
274: 275: 276: 277:
278: public function duplicate()
279: {
280: $this->copie = imagecreatetruecolor($this->width, $this->height);
281: imagecopy($this->copie, $this->source, 0, 0, 0, 0, $this->width, $this->height);
282: }
283:
284: 285: 286: 287:
288: public function restore()
289: {
290: $this->source = $this->copie;
291: }
292:
293: 294: 295: 296: 297:
298: public function setFont($path)
299: {
300: $font = new Font($path);
301: $this->font = $font->utilise();
302: }
303:
304: 305: 306: 307: 308: 309: 310: 311:
312: public function setColor($r, $v, $b)
313: {
314: return $this->couleur = imagecolorallocate($this->source, $r, $v, $b);
315: }
316:
317: 318: 319: 320: 321: 322: 323:
324: public function setBgColor($r, $v, $b)
325: {
326: imagefill($this->source, 0, 0, $this->setColor($r, $v, $b));
327: }
328:
329: 330: 331: 332: 333:
334: public function setType($type)
335: {
336: if ($this->type == null)
337: $this->type = intval($type);
338: }
339:
340: 341: 342: 343: 344: 345: 346: 347: 348: 349:
350: public function setText($texte, $size, $x, $y, $angle = 0, $rect = false)
351: {
352: if ($rect)
353: {
354: $rectText = imageftbbox($size, 0, $this->font, $texte);
355: $wText = abs($rectText[4] - $rectText[0]);
356: $hText = abs($rectText[1] - $rectText[5]);
357: $this->setColor(255, 255, 255);
358: imagefilledrectangle($this->source, $x, ($y - $hText), ($x + $wText + 5), ($y + 5), $this->couleur);
359:
360: $this->setColor(0, 0, 0);
361: imagettftext($this->source, $size, $angle, $x, $y, $this->couleur, $this->font, $texte);
362: }
363: else
364: {
365: imagettftext($this->source, $size, $angle, $x, $y, $this->couleur, $this->font, $texte);
366: }
367: }
368:
369: 370: 371: 372: 373: 374: 375:
376: public function rotate($angle)
377: {
378: $this->source = imagerotate($this->source, $angle, -1);
379: }
380:
381: 382: 383: 384: 385: 386: 387:
388: public function resize($newW, $newH)
389: {
390: if ($newW == 0)
391: {
392: $scale = $newH / $this->height;
393: $newW = $this->width * $scale;
394: }
395: elseif ($newH == 0)
396: {
397: $scale = $newW / $this->width;
398: $newH = $this->height * $scale;
399: }
400: $tempImg = imagecreatetruecolor($newW, $newH);
401:
402:
403: if (self::IMG_GIF == $this->type)
404: {
405: imagealphablending($tempImg, false);
406: imagesavealpha($tempImg, true);
407: $transparence = imagecolorallocatealpha($tempImg, 255, 255, 255, 127);
408: imagefilledrectangle($tempImg, 0, 0, $newW, $newH, $transparence);
409: imagecolortransparent($tempImg, $transparence);
410: }
411:
412: if (self::IMG_PNG == $this->type)
413: {
414: $background = imagecolorallocate($tempImg, 0, 0, 0);
415: imagecolortransparent($tempImg, $background);
416: imagealphablending($tempImg, false);
417: }
418:
419: if (imagecopyresampled($tempImg, $this->source, 0, 0, 0, 0, $newW, $newH, $this->width, $this->height))
420: {
421: $this->source = $tempImg;
422: $this->width = $newW;
423: $this->height = $newH;
424: return true;
425: }
426: else
427: {
428: return false;
429: }
430: }
431:
432: 433: 434: 435: 436: 437: 438: 439: 440:
441: public function miniaturise($newW, $newH, $color = "#000000")
442: {
443: $rgb = $this->hexToRgb($color);
444: $tempImg = imagecreatetruecolor($newW, $newH);
445: $color = imagecolorallocate($tempImg, $rgb[0], $rgb[1], $rgb[2]);
446: imagefill($tempImg, 0, 0, $color);
447:
448: if ($this->width == max($this->width, $this->height))
449: {
450: $this->resize($newW, null);
451: $dH = $newH - $this->height;
452: if (imagecopy($tempImg, $this->source, 0, ($dH / 2), 0, 0, $this->width, $this->height))
453: $this->source = $tempImg;
454: else
455: throw new \RuntimeException('Création de la miniature impossible');
456: }
457: else
458: {
459: $this->resize(null, $newH);
460: $dW = $newW - $this->width;
461: if (imagecopy($tempImg, $this->source, ($dW / 2), 0, 0, 0, $this->width, $this->height))
462: $this->source = $tempImg;
463: else
464: throw new \RuntimeException('Création de la miniature impossible');
465: }
466: }
467:
468: 469: 470: 471: 472: 473: 474: 475: 476:
477: public function crop($cropW, $cropH, $cropStartX, $cropStartY)
478: {
479: $tempImg = imagecreatetruecolor($cropW, $cropH);
480:
481: if (self::IMG_GIF == $this->type)
482: {
483: imagealphablending($tempImg, false);
484: imagesavealpha($tempImg, true);
485: $transparence = imagecolorallocatealpha($tempImg, 255, 255, 255, 127);
486: imagefilledrectangle($tempImg, 0, 0, $newW, $newH, $transparence);
487: imagecolortransparent($tempImg, $transparence);
488: }
489:
490: if (imagecopyresized($tempImg, $this->source, 0, 0, $cropStartX, $cropStartY, $cropW, $cropH, $cropW, $cropH))
491: {
492: $this->source = $tempImg;
493: $this->width = $cropW;
494: $this->height = $cropH;
495: return true;
496: }
497: else
498: {
499: return false;
500: }
501: }
502:
503: 504: 505: 506: 507: 508: 509:
510: public static function hexToRgb($color)
511: {
512: if ($color[0] == '#')
513: {
514: $color = substr($color, 1);
515: }
516: else if ($color[1] == 'x')
517: {
518: $color = substr($color, 2);
519: }
520: $rgb = array();
521: $rgb[0] = hexdec(substr($color, 0, 2));
522: $rgb[1] = hexdec(substr($color, 2, 2));
523: $rgb[2] = hexdec(substr($color, 4, 2));
524: return $rgb;
525: }
526:
527: 528: 529: 530: 531: 532: 533:
534: public static function RgbToHex($rgb)
535: {
536: for ($i = 0; $i < 2; $i++) {
537: if ($rgb[$i] < 0 || $rgb[$i] > 255)
538: throw new Exception('La valeur RGB est incorrecte (compris en 0 et 255');
539: }
540:
541: return str_pad((dechex($rgb[0]) . dechex($rgb[1]) . dechex($rgb[2])), 6, "0", STR_PAD_LEFT);
542: }
543:
544: 545: 546: 547: 548: 549:
550: public function setBorder($border, $color)
551: {
552: $couleur = $this->hexToRgb($color);
553: $this->setColor($couleur[0], $couleur[1], $couleur[2]);
554:
555: imagefilledrectangle($this->source, 0, 0, $border, $this->height, $this->couleur);
556:
557: imagefilledrectangle($this->source, $this->width - $border, 0, $this->width, $this->height, $this->couleur);
558:
559: imagefilledrectangle($this->source, 0, 0, $this->width, $border, $this->couleur);
560:
561: imagefilledrectangle($this->source, 0, $this->height - $border, $this->width, $this->height, $this->couleur);
562: }
563:
564: 565: 566: 567: 568: 569:
570: public function save($file, $qualite = 95)
571: {
572: if ($this->type == self::IMG_GIF)
573: {
574: if (imagegif($this->source, $file))
575: return true;
576: else
577: return false;
578: }
579: elseif ($this->type == self::IMG_JPG)
580: {
581: if (imagejpeg($this->source, $file, $qualite))
582: return true;
583: else
584: return false;
585: }
586: elseif ($this->type == self::IMG_PNG)
587: {
588: if (imagepng($this->source, $file))
589: return true;
590: else
591: return false;
592: }
593: }
594:
595: 596: 597: 598: 599:
600: public function display($qualite = 100)
601: {
602: if ($this->type == self::IMG_GIF)
603: {
604: header("Content-type: image/gif");
605: return imagegif($this->source);
606: }
607: elseif ($this->type == self::IMG_JPG)
608: {
609: header("Content-type: image/jpeg");
610: return imagejpeg($this->source, null, $qualite);
611: }
612: elseif ($this->type == self::IMG_PNG)
613: {
614: header("Content-type: image/png");
615: return imagepng($this->source);
616: }
617: }
618:
619: 620: 621: 622: 623: 624:
625: public function getSource()
626: {
627: return $this->source;
628: }
629:
630: 631: 632: 633: 634: 635:
636: public function setSource($resource)
637: {
638: if ($resource != null && is_resource($resource))
639: $this->source = $resource;
640: else
641: throw new Exception('La ressource n est pas valide.');
642: }
643:
644: 645: 646:
647: public function __destruct()
648: {
649: if (is_resource($this->source))
650: imagedestroy($this->source);
651:
652: if ($this->copie != null)
653: @imagedestroy($this->copie);
654: }
655:
656: }
657:
658: ?>