1: <?php
2: /**
3: ##DOC-SIGNATURE##
4:
5: This file is part of WideImage.
6:
7: WideImage is free software; you can redistribute it and/or modify
8: it under the terms of the GNU Lesser General Public License as published by
9: the Free Software Foundation; either version 2.1 of the License, or
10: (at your option) any later version.
11:
12: WideImage is distributed in the hope that it will be useful,
13: but WITHOUT ANY WARRANTY; without even the implied warranty of
14: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15: GNU Lesser General Public License for more details.
16:
17: You should have received a copy of the GNU Lesser General Public License
18: along with WideImage; if not, write to the Free Software
19: Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20:
21: * @package Internal/Operations
22: **/
23:
24: namespace WideImage\Operation;
25:
26: /**
27: * AutoCrop operation
28: *
29: * @package Internal/Operations
30: */
31: class AutoCrop
32: {
33: /**
34: * Executes the auto-crop operation on the $img
35: *
36: * @param \WideImage\Image $img
37: * @param int $rgb_threshold The difference in RGB from $base_color
38: * @param int $pixel_cutoff The number of pixels on each border that must be over $rgb_threshold
39: * @param int $base_color The color that will get cropped
40: * @return \WideImage\Image resulting auto-cropped image
41: */
42: public function execute($img, $margin, $rgb_threshold, $pixel_cutoff, $base_color)
43: {
44: $margin = intval($margin);
45:
46: $rgb_threshold = intval($rgb_threshold);
47:
48: if ($rgb_threshold < 0) {
49: $rgb_threshold = 0;
50: }
51:
52: $pixel_cutoff = intval($pixel_cutoff);
53: if ($pixel_cutoff <= 1) {
54: $pixel_cutoff = 1;
55: }
56:
57: if ($base_color === null) {
58: $rgb_base = $img->getRGBAt(0, 0);
59: } else {
60: if ($base_color < 0) {
61: return $img->copy();
62: }
63:
64: $rgb_base = $img->getColorRGB($base_color);
65: }
66:
67: $cut_rect = array('left' => 0, 'top' => 0, 'right' => $img->getWidth() - 1, 'bottom' => $img->getHeight() - 1);
68:
69: for ($y = 0; $y <= $cut_rect['bottom']; $y++) {
70: $count = 0;
71:
72: for ($x = 0; $x <= $cut_rect['right']; $x++) {
73: $rgb = $img->getRGBAt($x, $y);
74: $diff = abs($rgb['red'] - $rgb_base['red']) + abs($rgb['green'] - $rgb_base['green']) + abs($rgb['blue'] - $rgb_base['blue']);
75:
76: if ($diff > $rgb_threshold) {
77: $count++;
78:
79: if ($count >= $pixel_cutoff) {
80: $cut_rect['top'] = $y;
81: break 2;
82: }
83: }
84: }
85: }
86:
87: for ($y = $img->getHeight() - 1; $y >= $cut_rect['top']; $y--) {
88: $count = 0;
89:
90: for ($x = 0; $x <= $cut_rect['right']; $x++) {
91: $rgb = $img->getRGBAt($x, $y);
92: $diff = abs($rgb['red'] - $rgb_base['red']) + abs($rgb['green'] - $rgb_base['green']) + abs($rgb['blue'] - $rgb_base['blue']);
93:
94: if ($diff > $rgb_threshold) {
95: $count++;
96:
97: if ($count >= $pixel_cutoff) {
98: $cut_rect['bottom'] = $y;
99: break 2;
100: }
101: }
102: }
103: }
104:
105: for ($x = 0; $x <= $cut_rect['right']; $x++) {
106: $count = 0;
107:
108: for ($y = $cut_rect['top']; $y <= $cut_rect['bottom']; $y++) {
109: $rgb = $img->getRGBAt($x, $y);
110: $diff = abs($rgb['red'] - $rgb_base['red']) + abs($rgb['green'] - $rgb_base['green']) + abs($rgb['blue'] - $rgb_base['blue']);
111:
112: if ($diff > $rgb_threshold) {
113: $count++;
114:
115: if ($count >= $pixel_cutoff) {
116: $cut_rect['left'] = $x;
117: break 2;
118: }
119: }
120: }
121: }
122:
123: for ($x = $cut_rect['right']; $x >= $cut_rect['left']; $x--) {
124: $count = 0;
125:
126: for ($y = $cut_rect['top']; $y <= $cut_rect['bottom']; $y++) {
127: $rgb = $img->getRGBAt($x, $y);
128: $diff = abs($rgb['red'] - $rgb_base['red']) + abs($rgb['green'] - $rgb_base['green']) + abs($rgb['blue'] - $rgb_base['blue']);
129:
130: if ($diff > $rgb_threshold) {
131: $count++;
132:
133: if ($count >= $pixel_cutoff) {
134: $cut_rect['right'] = $x;
135: break 2;
136: }
137: }
138: }
139: }
140:
141: $cut_rect = array(
142: 'left' => $cut_rect['left'] - $margin,
143: 'top' => $cut_rect['top'] - $margin,
144: 'right' => $cut_rect['right'] + $margin,
145: 'bottom' => $cut_rect['bottom'] + $margin
146: );
147:
148: if ($cut_rect['left'] < 0) {
149: $cut_rect['left'] = 0;
150: }
151:
152: if ($cut_rect['top'] < 0) {
153: $cut_rect['top'] = 0;
154: }
155:
156: if ($cut_rect['right'] >= $img->getWidth()) {
157: $cut_rect['right'] = $img->getWidth() - 1;
158: }
159:
160: if ($cut_rect['bottom'] >= $img->getHeight()) {
161: $cut_rect['bottom'] = $img->getHeight() - 1;
162: }
163:
164: return $img->crop($cut_rect['left'], $cut_rect['top'], $cut_rect['right'] - $cut_rect['left'] + 1, $cut_rect['bottom'] - $cut_rect['top'] + 1);
165: }
166: }
167: