1: <?php
2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14:
15: class Horde_Image_Effect_Imagick_SmartCrop extends Horde_Image_Effect
16: {
17: 18: 19: 20: 21: 22: 23: 24: 25:
26: protected $_params = array();
27:
28: public function apply()
29: {
30: $this->_params = new Horde_Support_Array($this->_params);
31:
32:
33: $geometry = $this->_image->getDimensions();
34: $w0 = $geometry['width'];
35: $h0 = $geometry['height'];
36:
37: $w = $this->_params->width;
38: $h = $this->_params->height;
39:
40:
41: $r = 1;
42: $nk = 9;
43: $gamma = 0.2;
44:
45:
46: $ar = $this->_params->width / $this->_params->height;
47:
48:
49: $ar0 = $w0 / $h0;
50:
51: $this->_logger->debug(sprintf("SmartCrop: %d x %d => %d x %d ", $w0, $h0, $w, $h));
52: $this->_logger->debug('OAR: ' . $ar0);
53: $this->_logger->debug('TAR: ' . $ar);
54:
55:
56:
57: $img = $this->_image->imagick->clone();
58: $img->edgeImage($r);
59: $img->modulateImage(100,0,100);
60: $img->blackThresholdImage("#0f0f0f");
61:
62: $xcenter = $ycenter = $sum = 0;
63: $n = 100000;
64: for ($k = 0; $k < $n; $k++) {
65: $i = mt_rand(0, $w0 - 1);
66: $j = mt_rand(0, $h0 - 1);
67: $pixel = $img->getImagePixelColor($i, $j);
68: $val = $pixel->getColor();
69: $val = $val['b'];
70: $sum += $val;
71: $xcenter = $xcenter + ($i + 1) * $val;
72: $ycenter = $ycenter + ($j + 1) * $val;
73: }
74: $xcenter /= $sum;
75: $ycenter /= $sum;
76: $this->_logger->debug('COE: ' . $xcenter . 'x' . $ycenter);
77:
78:
79: if ($w0 / $h0 > $ar) {
80:
81:
82: $wcrop0 = round($ar * $h0);
83: $hcrop0 = $h0;
84: } else {
85:
86: $wcrop0 = $w0;
87: $hcrop0 = round($w0 / $ar);
88: }
89:
90:
91: $params = array();
92:
93:
94: $hgap = $hcrop0 - $h;
95: $hinc = ($nk == 1) ? 0 : $hgap / ($nk - 1);
96: $wgap = $wcrop0 - $w;
97: $winc = ($nk == 1) ? 0 : $wgap / ($nk - 1);
98:
99:
100: $n = 10000;
101: $maxbetanorm = 0;
102: $maxfile = '';
103: $maxparam = array('w' => 0,
104: 'h' => 0,
105: 'x' => 0,
106: 'y' => 0);
107:
108: for ($k = 0; $k < $nk; $k++) {
109: $hcrop = round($hcrop0 - $k * $hinc);
110: $wcrop = round($wcrop0 - $k * $winc);
111: $xcrop = $xcenter - $wcrop / 2;
112: $ycrop = $ycenter - $hcrop / 2;
113: if ($xcrop < 0) {
114: $xcrop = 0;
115: }
116: if ($xcrop + $wcrop > $w0) {
117: $xcrop = $w0 - $wcrop;
118: }
119: if ($ycrop < 0) {
120: $ycrop = 0;
121: }
122: if ($ycrop+$hcrop > $h0) {
123: $ycrop = $h0 - $hcrop;
124: }
125: $this->_logger->debug("crop: $wcrop, $hcrop, $xcrop, $ycrop");
126:
127: $beta = 0;
128: for ($c = 0; $c < $n; $c++) {
129: $i = mt_rand(0, $wcrop - 1);
130: $j = mt_rand(0, $hcrop - 1);
131: $pixel = $img->getImagePixelColor($xcrop + $i, $ycrop + $j);
132: $val = $pixel->getColor();
133: $beta += $val['b'];
134: }
135:
136: $area = $wcrop * $hcrop;
137: $betanorm = $beta / ($n * pow($area, $gamma - 1));
138:
139:
140: if ($betanorm > $maxbetanorm) {
141: $this->_logger->debug('Found best');
142: $maxbetanorm = $betanorm;
143: $maxparam['w'] = $wcrop;
144: $maxparam['h'] = $hcrop;
145: $maxparam['x'] = $xcrop;
146: $maxparam['y'] = $ycrop;
147: }
148: }
149:
150: $this->_logger->debug('Cropping');
151:
152: $this->_image->imagick->cropImage($maxparam['w'],
153: $maxparam['h'],
154: $maxparam['x'],
155: $maxparam['y']);
156: $this->_image->imagick->scaleImage($w, $h);
157: $img->destroy();
158: }
159:
160: }