1: <?php
2:
3: 4: 5: 6: 7: 8: 9: 10: 11:
12: class Image
13: {
14: 15: 16:
17: private $image;
18:
19:
20: 21: 22:
23: private $file;
24:
25:
26: 27: 28:
29: private $width;
30:
31:
32: 33: 34:
35: private $height;
36:
37:
38: 39: 40:
41: private $type;
42:
43:
44: 45: 46:
47: private $quality = 85;
48:
49:
50: 51: 52:
53: const FIT = 1;
54: const FILL = 2;
55: const HEIGHT = 4;
56: const WIDTH = 8;
57: const ENLARGE = 16;
58: const STRETCH = 32;
59:
60:
61: 62: 63: 64: 65: 66:
67: public static function load($file)
68: {
69: $image = new self;
70:
71: $info = @getimagesize($file);
72: if ($info === FALSE) {
73: return FALSE;
74: }
75:
76: $image->file = $file;
77: $image->width = $info[0];
78: $image->height = $info[1];
79: $image->type = $info[2];
80:
81: $image_data = file_get_contents($file);
82: if ($image_data === FALSE) {
83: return FALSE;
84: }
85:
86: $image->image = imagecreatefromstring($image_data);
87:
88:
89:
90:
91: return $image;
92: }
93:
94:
95: public static function blank($width, $height)
96: {
97: $image = new self;
98:
99: $image->width = $width;
100: $image->height = $height;
101: $image->type = 3;
102:
103: $image->image = imagecreatetruecolor($width, $height);
104:
105: imagealphablending($image->image, FALSE);
106: imagesavealpha($image->image, TRUE);
107:
108: $transparent = imagecolorallocatealpha($image->image, 255, 255, 255, 127);
109: imagefill($image->image, 0, 0, $transparent);
110:
111: return $image;
112: }
113:
114:
115: 116: 117: 118: 119: 120: 121: 122:
123: public function resize($width, $height, $flags = 0)
124: {
125: list($width, $height) = $this->calculate_new_size($width, $height, $flags);
126: $new_image = imagecreatetruecolor($width, $height);
127: imagecopyresampled($new_image, $this->image, 0, 0, 0, 0, $width, $height, $this->width, $this->height);
128:
129: $this->image = $new_image;
130: $this->width = $width;
131: $this->height = $height;
132:
133: return $this;
134: }
135:
136:
137: 138: 139: 140: 141: 142: 143: 144: 145:
146: public function crop($width, $height, $left = NULL, $top = NULL)
147: {
148: list($width, $height, $left, $top) = $this->calculate_crop($width, $height, $left, $top);
149:
150: $canvas = imagecreatetruecolor($width, $height);
151: imagecopy($canvas, $this->image, 0, 0, $left, $top, $this->width, $this->height);
152:
153: $this->image = $canvas;
154: $this->width = $width;
155: $this->height = $height;
156:
157: return $this;
158: }
159:
160:
161: 162: 163: 164: 165: 166:
167: public function rotate($angle)
168: {
169: $angle = floor($angle / 90);
170: $angle = round($angle * 90);
171:
172: if ($angle === 0
173: OR $angle === 360) {
174:
175: return $this;
176: }
177:
178: for ($a = 0; $a < ($angle / 90); $a++) {
179: $canvas = imagecreatetruecolor($this->height, $this->width);
180: imagealphablending($canvas, false);
181: imagesavealpha($canvas, true);
182:
183: for($w = 0; $w < $this->width; $w++) {
184: for($h = 0; $h < $this->height; $h++) {
185: $pixel = imagecolorat($this->image, $w, $h);
186: imagesetpixel($canvas, $h, ($this->width - 1) - $w, $pixel);
187: }
188: }
189:
190: $this->image = $canvas;
191: $this->width = imagesx($this->image);
192: $this->height = imagesy($this->image);
193: }
194:
195: return $this;
196: }
197:
198:
199: 200: 201: 202: 203: 204: 205: 206:
207: public function watermark($file, $left = 'center', $top = 'center')
208: {
209: $watermark = imagecreatefromstring(file_get_contents($file));
210: $watermark_width = imagesx($watermark);
211: $watermark_height = imagesy($watermark);
212:
213: list($left, $top) = $this->calculate_watermark_position($left, $top, $watermark_width, $watermark_height);
214:
215: imagecopy($this->image, $watermark, $left, $top, 0, 0, $watermark_width, $watermark_height);
216:
217: return $this;
218: }
219:
220:
221: 222: 223: 224: 225:
226: public function to_grayscale()
227: {
228: imagefilter($this->image, IMG_FILTER_GRAYSCALE);
229:
230: return $this;
231: }
232:
233:
234: 235: 236: 237: 238:
239: public function sharpen()
240: {
241: imageconvolution($this->image, array(
242: array( -1, -1, -1 ),
243: array( -1, 24, -1 ),
244: array( -1, -1, -1 ),
245: ), 16, 0);
246: return $this;
247: }
248:
249:
250: public function stripes()
251: {
252: $max_line_width = mt_rand(1, 10);
253: $color_deviation = mt_rand(10, 40);
254:
255: $lr = mt_rand(0, 255);
256: $lg = mt_rand(0, 255);
257: $lb = mt_rand(0, 255);
258:
259: $width = 0;
260:
261: while($width < $this->width) {
262: $lr = mt_rand($lr - $color_deviation, $lr + $color_deviation);
263: $lg = mt_rand($lg - $color_deviation, $lg + $color_deviation);
264: $lb = mt_rand($lb - $color_deviation, $lb + $color_deviation);
265:
266: $linecolor = imagecolorallocate(
267: $this->image,
268: $cr = max(0, min($lr, 255)),
269: $cg = max(0, min($lg, 255)),
270: $cb = max(0, min($lb, 255))
271: );
272:
273: $linewidth = mt_rand(1, $max_line_width);
274: imagefilledrectangle($this->image, $width, 0, $width + $linewidth, $this->height, $linecolor);
275: $width += $linewidth;
276: $lr = $cr;
277: $lg = $cg;
278: $lb = $cb;
279: }
280:
281: return $this;
282: }
283:
284:
285: public function color($r, $g = NULL, $b = NULL, $alpha = 0)
286: {
287: if ($g === NULL
288: OR $b === NULL) {
289:
290: if ($g !== NULL) {
291: $alpha = $g;
292: }
293:
294: $color = hexdec($r);
295: $r = 0xFF & ($color >> 0x10);
296: $g = 0xFF & ($color >> 0x8);
297: $b = 0xFF & $color;
298: }
299:
300: $color = imagecolorallocatealpha($this->image, $r, $g, $b, $alpha);
301:
302: imagefilledrectangle($this->image, 0, 0, $this->width, $this->height, $color);
303:
304: return $this;
305: }
306:
307:
308: public function from_string($string)
309: {
310: $hash = md5($string);
311:
312: $sprite_z = max($this->width, $this->height);
313:
314:
315: $csh = hexdec(substr($hash, 0, 1));
316: $ssh = hexdec(substr($hash, 1, 1));
317: $xsh = hexdec(substr($hash, 2, 1)) & 7;
318:
319: $cro = hexdec(substr($hash, 3, 1)) & 3;
320: $sro = hexdec(substr($hash, 4, 1)) & 3;
321: $xbg = hexdec(substr($hash, 5, 1)) % 2;
322:
323:
324: $cfr = hexdec(substr($hash, 6, 2));
325: $cfg = hexdec(substr($hash, 8, 2));
326: $cfb = hexdec(substr($hash, 10, 2));
327:
328:
329: $sfr = hexdec(substr($hash, 12, 2));
330: $sfg = hexdec(substr($hash, 14, 2));
331: $sfb = hexdec(substr($hash, 16, 2));
332:
333:
334: $angle = hexdec(substr($hash, 18, 2));
335:
336:
337: $identicon = imagecreatetruecolor($sprite_z * 3, $sprite_z * 3);
338: imageantialias($identicon, TRUE);
339: imagealphablending($identicon, FALSE);
340: imagesavealpha($identicon, TRUE);
341:
342:
343: $bg = imagecolorallocatealpha($identicon, 255, 255, 255, 127);
344: imagefilledrectangle($identicon, 0, 0, $sprite_z, $sprite_z, $bg);
345:
346:
347: $corner = $this->from_string_get_sprite($sprite_z, $csh, $cfr, $cfg, $cfb, $cro);
348: imagecopy($identicon, $corner, 0, 0, 0, 0, $sprite_z, $sprite_z);
349:
350: $corner = imagerotate($corner, 90, $bg);
351: imagecopy($identicon, $corner, 0, $sprite_z * 2, 0, 0, $sprite_z, $sprite_z);
352:
353: $corner = imagerotate($corner, 90, $bg);
354: imagecopy($identicon, $corner, $sprite_z * 2, $sprite_z * 2, 0, 0, $sprite_z, $sprite_z);
355:
356: $corner = imagerotate($corner, 90, $bg);
357: imagecopy($identicon, $corner, $sprite_z * 2, 0, 0, 0, $sprite_z, $sprite_z);
358:
359:
360: $side = $this->from_string_get_sprite($sprite_z, $ssh, $sfr, $sfg, $sfb, $sro);
361: imagecopy($identicon, $side, $sprite_z, 0, 0, 0, $sprite_z, $sprite_z);
362:
363: $side = imagerotate($side, 90, $bg);
364: imagecopy($identicon, $side, 0, $sprite_z, 0, 0, $sprite_z, $sprite_z);
365:
366: $side = imagerotate($side, 90, $bg);
367: imagecopy($identicon, $side, $sprite_z, $sprite_z * 2, 0, 0, $sprite_z, $sprite_z);
368:
369: $side = imagerotate($side, 90, $bg);
370: imagecopy($identicon, $side, $sprite_z * 2, $sprite_z, 0, 0, $sprite_z, $sprite_z);
371:
372:
373: $center = $this->from_string_get_center($sprite_z, $xsh, $cfr, $cfg, $cfb, $sfr, $sfg, $sfb, $xbg);
374: imagecopy($identicon, $center, $sprite_z, $sprite_z, 0, 0, $sprite_z, $sprite_z);
375:
376:
377: $resized = imagecreatetruecolor($this->width, $this->height);
378: imageantialias($resized, TRUE);
379: imagealphablending($resized, FALSE);
380: imagesavealpha($resized, TRUE);
381:
382:
383: imagecopyresampled($resized, $identicon, 0, 0, 0, 0, $this->width, $this->height, $sprite_z * 3, $sprite_z * 3);
384:
385: $this->blend($resized);
386:
387: return $this;
388: }
389:
390:
391:
392: private function from_string_get_sprite($sprite_z, $shape, $R, $G, $B, $rotation) {
393: $sprite = imagecreatetruecolor($sprite_z, $sprite_z);
394: imageantialias($sprite, TRUE);
395: imagealphablending($sprite, FALSE);
396: imagesavealpha($sprite, TRUE);
397:
398: $fg = imagecolorallocate($sprite, $R, $G, $B);
399: $bg = imagecolorallocatealpha($sprite, 255, 255, 255, 127);
400: imagefilledrectangle($sprite, 0, 0, $sprite_z, $sprite_z, $bg);
401:
402: switch($shape) {
403: case 0:
404: $shape = array(
405: 0.5, 1,
406: 1, 0,
407: 1, 1
408: );
409: break;
410: case 1:
411: $shape = array(
412: 0.5, 0,
413: 1, 0,
414: 0.5, 1,
415: 0, 1
416: );
417: break;
418: case 2:
419: $shape = array(
420: 0.5, 0,
421: 1, 0,
422: 1, 1,
423: 0.5, 1,
424: 1, 0.5
425: );
426: break;
427: case 3:
428: $shape = array(
429: 0, 0.5,
430: 0.5, 0,
431: 1, 0.5,
432: 0.5, 1,
433: 0.5, 0.5
434: );
435: break;
436: case 4:
437: $shape = array(
438: 0, 0.5,
439: 1, 0,
440: 1, 1,
441: 0, 1,
442: 1, 0.5
443: );
444: break;
445: case 5:
446: $shape = array(
447: 1,0,
448: 1,1,
449: 0.5,1,
450: 1,0.5,
451: 0.5,0.5
452: );
453: break;
454: case 6:
455: $shape = array(
456: 0, 0,
457: 1, 0,
458: 1, 0.5,
459: 0, 0,
460: 0.5, 1,
461: 0, 1
462: );
463: break;
464: case 7:
465: $shape = array(
466: 0, 0,
467: 0.5, 0,
468: 1, 0.5,
469: 0.5, 1,
470: 0, 1,
471: 0.5, 0.5
472: );
473: break;
474: case 8:
475: $shape = array(
476: 0.5, 0,
477: 0.5, 0.5,
478: 1, 0.5,
479: 1, 1,
480: 0.5, 1,
481: 0.5, 0.5,
482: 0, 0.5
483: );
484: break;
485: case 9:
486: $shape = array(
487: 0, 0,
488: 1, 0,
489: 0.5, 0.5,
490: 1, 0.5,
491: 0.5, 1,
492: 0.5, 0.5,
493: 0, 1
494: );
495: break;
496: case 10:
497: $shape = array(
498: 0, 0.5,
499: 0.5, 1,
500: 1, 0.5,
501: 0.5, 0,
502: 1, 0,
503: 1, 1,
504: 0, 1
505: );
506: break;
507: case 11:
508: $shape = array(
509: 0.5, 0,
510: 1, 0,
511: 1, 1,
512: 0.5, 1,
513: 1, 0.75,
514: 0.5, 0.5,
515: 1, 0.25
516: );
517: break;
518: case 12:
519: $shape = array(
520: 0, 0.5,
521: 0.5, 0,
522: 0.5, 0.5,
523: 1, 0,
524: 1, 0.5,
525: 0.5, 1,
526: 0.5, 0.5,
527: 0, 1
528: );
529: break;
530: case 13:
531: $shape = array(
532: 0, 0,
533: 1, 0,
534: 1, 1,
535: 0, 1,
536: 1, 0.5,
537: 0.5, 0.25,
538: 0.5, 0.75,
539: 0, 0.5,
540: 0.5, 0.25
541: );
542: break;
543: case 14:
544: $shape = array(
545: 0, 0.5,
546: 0.5, 0.5,
547: 0.5, 0,
548: 1, 0,
549: 0.5, 0.5,
550: 1, 0.5,
551: 0.5, 1,
552: 0.5, 0.5,
553: 0, 1
554: );
555: break;
556: default:
557: $shape = array(
558: 0, 0,
559: 1, 0,
560: 0.5, 0.5,
561: 0.5, 0,
562: 0, 0.5,
563: 1, 0.5,
564: 0.5, 1,
565: 0.5, 0.5,
566: 0, 1
567: );
568: break;
569: }
570:
571: for ($i = 0; $i < count($shape); $i++) {
572: $shape[$i] = $shape[$i] * $sprite_z;
573: }
574:
575: imagefilledpolygon($sprite, $shape, count($shape) / 2, $fg);
576:
577:
578: for ($i = 0; $i < $rotation; $i++) {
579: $sprite = imagerotate($sprite, 90, $bg);
580: }
581:
582: return $sprite;
583: }
584:
585:
586: private function from_string_get_center($sprite_z, $shape, $fR, $fG, $fB, $bR, $bG, $bB, $usebg) {
587: $sprite = imagecreatetruecolor($sprite_z, $sprite_z);
588: imageantialias($sprite, TRUE);
589: imagealphablending($sprite, FALSE);
590: imagesavealpha($sprite, TRUE);
591:
592: $fg = imagecolorallocate($sprite, $fR, $fG, $fB);
593:
594:
595: if ($usebg > 0
596: AND (abs($fR - $bR) > 127
597: OR abs($fG - $bG) > 127
598: OR abs($fB - $bB) > 127)) {
599:
600: $bg = imagecolorallocatealpha($sprite, $bR, $bG, $bB, 127);
601:
602: } else {
603: $bg = imagecolorallocatealpha($sprite, 255, 255, 255, 127);
604: }
605:
606: imagefilledrectangle($sprite, 0, 0, $sprite_z, $sprite_z, $bg);
607:
608: switch($shape) {
609: case 0:
610: $shape=array();
611: break;
612: case 1:
613: $shape=array(
614: 0, 0,
615: 1, 0,
616: 1, 1,
617: 0, 1
618: );
619: break;
620: case 2:
621: $shape=array(
622: 0.5, 0,
623: 1, 0.5,
624: 0.5, 1,
625: 0, 0.5
626: );
627: break;
628: case 3:
629: $shape=array(
630: 0, 0,
631: 1, 0,
632: 1, 1,
633: 0, 1,
634: 0, 0.5,
635: 0.5, 1,
636: 1, 0.5,
637: 0.5, 0,
638: 0, 0.5
639: );
640: break;
641: case 4:
642: $shape=array(
643: 0.25, 0,
644: 0.75, 0,
645: 0.5, 0.5,
646: 1, 0.25,
647: 1, 0.75,
648: 0.5, 0.5,
649: 0.75, 1,
650: 0.25, 1,
651: 0.5, 0.5,
652: 0, 0.75,
653: 0, 0.25,
654: 0.5, 0.5
655: );
656: break;
657: case 5:
658: $shape=array(
659: 0, 0,
660: 0.5, 0.25,
661: 1, 0,
662: 0.75, 0.5,
663: 1, 1,
664: 0.5, 0.75,
665: 0, 1,
666: 0.25, 0.5
667: );
668: break;
669: case 6:
670: $shape=array(
671: 0.33, 0.33,
672: 0.67, 0.33,
673: 0.67, 0.67,
674: 0.33, 0.67
675: );
676: break;
677: case 7:
678: $shape=array(
679: 0, 0,
680: 0.33, 0,
681: 0.33, 0.33,
682: 0.66, 0.33,
683: 0.67, 0,
684: 1, 0,
685: 1, 0.33,
686: 0.67, 0.33,
687: 0.67, 0.67,
688: 1, 0.67,
689: 1, 1,
690: 0.67, 1,
691: 0.67, 0.67,
692: 0.33, 0.67,
693: 0.33, 1,
694: 0, 1,
695: 0, 0.67,
696: 0.33, 0.67,
697: 0.33, 0.33,
698: 0, 0.33
699: );
700: break;
701: }
702:
703: for ($i = 0; $i < count($shape); $i++) {
704: $shape[$i] = $shape[$i] * $sprite_z;
705: }
706:
707: if (count($shape) > 0) {
708: imagefilledpolygon($sprite, $shape, count($shape) / 2, $fg);
709: }
710:
711: return $sprite;
712: }
713:
714:
715: 716: 717: 718: 719: 720: 721:
722: public function save($file = NULL, $mime = NULL)
723: {
724: if ($file === NULL) {
725: $file = $this->file;
726: }
727:
728: if ($mime === NULL) {
729: $ext = pathinfo($file, PATHINFO_EXTENSION);
730:
731: if (empty($ext) === FALSE
732: AND in_array($ext, array('png', 'jpg', 'jpeg', 'gif')) === TRUE) {
733:
734: switch ($ext) {
735: case 'jpg':
736: case 'jpeg':
737: $mime = 'image/jpeg';
738: break;
739:
740: case 'png':
741: $mime = 'image/png';
742: break;
743:
744: case 'gif':
745: $mime = 'image/gif';
746: break;
747: }
748:
749: } else {
750: $mime = $this->get_type('mime');
751: }
752: }
753:
754: switch ($mime) {
755: case 'image/jpeg':
756: return imagejpeg($this->image, $file, $this->quality);
757:
758: case 'image/png':
759: $quality = round($this->quality / 11.111111);
760: return imagepng($this->image, $file, $quality);
761:
762: case 'image/gif':
763: return imagegif($this->image, $file);
764: }
765: }
766:
767:
768: 769: 770: 771: 772: 773:
774: public function send($mime = NULL)
775: {
776: if ($mime === NULL) {
777: $mime = $this->get_type('mime');
778: }
779:
780: header('Content-Type: ' . $mime);
781:
782: switch ($mime) {
783: case 'image/jpeg':
784: imagejpeg($this->image, NULL, $this->quality);
785:
786: case 'image/png':
787: $quality = round($this->quality / 11.111111);
788: imagepng($this->image, NULL, $quality);
789:
790: case 'image/gif':
791: imagegif($this->image, NULL);
792: }
793:
794: exit;
795: }
796:
797:
798: 799: 800: 801: 802:
803: public function get_width()
804: {
805: return $this->width;
806: }
807:
808:
809: 810: 811: 812: 813:
814: public function get_height()
815: {
816: return $this->width;
817: }
818:
819:
820: 821: 822: 823: 824: 825:
826: public function get_type($format = 'extension')
827: {
828: $types = array(
829: 1 => 'gif',
830: 2 => 'jpg',
831: 3 => 'png'
832: );
833:
834: if ($format === 'mime') {
835: $types = array(
836: 1 => 'image/gif',
837: 2 => 'image/jpeg',
838: 3 => 'image/png'
839: );
840: }
841:
842: return $types[$this->type];
843: }
844:
845:
846: 847: 848: 849: 850: 851: 852: 853:
854: private function calculate_new_size($new_width, $new_height, $flags)
855: {
856: $target_width = $new_width;
857: $target_height = $new_height;
858:
859:
860: if (($flags & self::STRETCH) == TRUE) {
861:
862: if (($flags & self::ENLARGE) == TRUE) {
863: return array($new_width, $new_height);
864: }
865:
866:
867: if ($this->width < $new_width) {
868: $new_width = $this->width;
869: }
870:
871: if ($this->height < $new_height) {
872: $new_height = $this->height;
873: }
874:
875: return array($new_width, $new_height);
876: }
877:
878: if (($this->width < $new_width
879: AND $this->height < $new_height)
880: AND ($flags & self::ENLARGE) == FALSE) {
881:
882: return array($this->width, $this->height);
883: }
884:
885: if (($flags & self::FILL) == FALSE) {
886: if ($this->width > $this->height) {
887: $new_height = NULL;
888:
889: } else {
890: $new_width = NULL;
891: }
892:
893: } elseif (($flags & self::FILL) == TRUE) {
894: if ($this->width > $this->height) {
895: $new_width = NULL;
896:
897: } else {
898: $new_height = NULL;
899: }
900:
901: } elseif (($flags & self::WIDTH) == TRUE) {
902: $new_height = NULL;
903:
904: } elseif (($flags & self::HEIGHT) == TRUE) {
905: $new_width = NULL;
906: }
907:
908: if ($new_height === NULL) {
909: $new_height = round($this->height * $new_width / $this->width);
910: }
911:
912: if ($new_width === NULL) {
913: $new_width = round($this->width * $new_height / $this->height);
914: }
915:
916: if ($flags & self::FIT == TRUE) {
917: if ($target_width < $new_width) {
918: $new_width = $target_width;
919: $new_height = NULL;
920:
921: } elseif ($target_height < $new_height) {
922: $hew_height = $target_height;
923: $new_width = NULL;
924: }
925:
926: if ($new_height === NULL) {
927: $new_height = round($this->height * $new_width / $this->width);
928: }
929:
930: if ($new_width === NULL) {
931: $new_width = round($this->width * $new_height / $this->height);
932: }
933: }
934:
935: return array((int) $new_width, (int) $new_height);
936: }
937:
938:
939: 940: 941: 942: 943: 944: 945: 946: 947:
948: private function calculate_crop($width, $height, $left = NULL, $top = NULL)
949: {
950: if ($left === NULL) {
951: $left = ($this->width - $width) / 2;
952: }
953:
954: if ($top === NULL) {
955: $top = ($this->height - $height) / 2;
956: }
957:
958: if ($width > $this->width) {
959: $width = $this->width;
960: $left = 0;
961: }
962:
963: if ($height > $this->height) {
964: $height = $this->height;
965: $top = 0;
966: }
967:
968: if (($width + $left) > $this->width) {
969: $left = $this->width - $width;
970: }
971:
972: if (($height + $left) > $this->height) {
973: $top = $this->height - $height;
974: }
975:
976: return array($width, $height, $left, $top);
977: }
978:
979:
980: 981: 982: 983: 984: 985: 986: 987: 988:
989: private function calculate_watermark_position($left, $top, $watermark_width, $watermark_height)
990: {
991: if ($left === 'center') {
992: $left = ($this->width - $watermark_width) / 2;
993:
994: } elseif ($left === 'left') {
995: $left = 0;
996:
997: } elseif ($left === 'right') {
998: $left = $this->width - $watermark_width;
999: }
1000:
1001: if ($top === 'center') {
1002: $top = ($this->height - $watermark_height) / 2;
1003:
1004: } elseif ($top === 'top') {
1005: $top = 0;
1006:
1007: } elseif ($top === 'bottom') {
1008: $top = $this->height - $watermark_height;
1009: }
1010:
1011: return array(max($left, 0), max($top, 0));
1012: }
1013:
1014:
1015: private function blend($second_image)
1016: {
1017:
1018: $out = $this->image;
1019:
1020:
1021: imagealphablending($out, TRUE);
1022: imagesavealpha($out, TRUE);
1023:
1024: imagecopy($out, $second_image, 0, 0, 0, 0, $this->width, $this->height);
1025:
1026:
1027: imagealphablending($out, FALSE);
1028:
1029:
1030:
1031: for($x = 0; $x < $this->width; $x++) {
1032: for($y = 0; $y < $this->height; $y++) {
1033: $alpha = 0;
1034:
1035: $color_index_1 = imagecolorat($out, $x, $y);
1036: $color_1 = imagecolorsforindex($out, $color_index_1);
1037: $alpha += 127 - $color_1['alpha'];
1038:
1039: $color_index_2 = imagecolorat($second_image, $x, $y);
1040: $color_2 = imagecolorsforindex($second_image, $color_index_2);
1041: $alpha += 127 - $color_2['alpha'];
1042:
1043: $alpha = min(127, $alpha);
1044: $color = imagecolorallocatealpha($out, $color_1['red'], $color_1['green'], $color_1['blue'], 127 - $alpha);
1045:
1046: imagesetpixel($out, $x, $y, $color);
1047: }
1048: }
1049:
1050:
1051:
1052: $this->image = $out;
1053: }
1054: }
1055: