$this->_logger = $logger;
}
- public function factory($type, $driver, $params)
+ static public function factory($type, $driver, $params)
{
if (is_array($type)) {
list($app, $type) = $type;
@include_once $path;
}
}
+
if (class_exists($class)) {
$effect = new $class($params);
} else {
+ $params['logger']->err(sprintf("Horde_Image_Effect %s for %s driver not found.", $type, $driver));
throw new Horde_Image_Exception(sprintf("Horde_Image_Effect %s for %s driver not found.", $type, $driver));
}
public function apply()
{
+ mt_srand(1);
$this->_params = new Horde_Support_Array($this->_params);
// Existing geometry
$w0 = $geometry['width'];
$h0 = $geometry['height'];
+ $w = $this->_params->width;
+ $h = $this->_params->height;
+
// @TODO: Parameterize these
$r = 1; // radius of edge filter
$nk = 9; // scale count: number of crop sizes to try
$ar = $this->_params->width / $this->_params->height;
// Existing AR
- $ar0 = $w0/$h0;
+ $ar0 = $w0 / $h0;
+
+ $this->_logger->debug(sprintf("SmartCrop: %d x %d => %d x %d ", $w0, $h0, $w, $h));
+ $this->_logger->debug('OAR: ' . $ar0);
+ $this->_logger->debug('TAR: ' . $ar);
+
// Compute COE
$img = $this->_image->imagick->clone();
$img->modulateImage(100,0,100);
$img->blackThresholdImage("#0f0f0f");
- // Get a 1x1 iterator (only way to get a single pixel's info without
- // iterating the entire row.
$xcenter = $ycenter = $sum = 0;
$n = 100000;
for ($k = 0; $k < $n; $k++) {
$i = mt_rand(0, $w0 - 1);
$j = mt_rand(0, $h0 - 1);
- // A single pixel iterator!
- $itr = $img->getPixelRegionIterator($i, $j, 1, 1);
- foreach ($itr as $row => $pixels) {
- foreach ($pixels as $col => $pixel) {
- $val = $pixel->getColor();
- }
- }
-
+ $pixel = $img->getImagePixelColor($i, $j);
+ $val = $pixel->getColor();
+ $val = $val['b'];
$sum += $val;
- $xcenter += ($i + 1) * $val;
- $ycenter += ($j + 1) * $val;
+ $xcenter = $xcenter + ($i + 1) * $val;
+ $ycenter = $ycenter + ($j + 1) * $val;
}
-
$xcenter /= $sum;
$ycenter /= $sum;
-
+ $this->_logger->debug('COE: ' . $xcenter . 'x' . $ycenter);
+
// crop source img to target AR
- if ($w0/$h0 > $ar) {
+ if ($w0 / $h0 > $ar) {
// source AR wider than target
// crop width to target AR
$wcrop0 = round($ar * $h0);
if ($ycrop+$hcrop > $h0) {
$ycrop = $h0 - $hcrop;
}
+ $this->_logger->debug("crop: $wcrop, $hcrop, $xcrop, $ycrop");
$beta = 0;
for ($c = 0; $c < $n; $c++) {
$i = mt_rand(0, $wcrop - 1);
$j = mt_rand(0, $hcrop - 1);
- $itr = $img->getPixelRegionIterator($xcrop + $i, $ycrop + $j, 1, 1);
- foreach ($itr as $row => $pixels) {
- foreach ($pixels as $col => $pixel) {
- $val = $pixel->getColor();
- }
- }
- $beta += $val & 0xFF;
+ $pixel = $img->getImagePixelColor($xcrop + $i, $ycrop + $j);
+ $val = $pixel->getColor();
+ $beta += $val['b'];// & 0xFF;
}
$area = $wcrop * $hcrop;
// best image found, save the params
if ($betanorm > $maxbetanorm) {
+ $this->_logger->debug('Found best');
$maxbetanorm = $betanorm;
$maxparam['w'] = $wcrop;
$maxparam['h'] = $hcrop;
}
}
+ $this->_logger->debug('Cropping');
// Crop to best
$this->_image->imagick->cropImage($maxparam['w'],
$maxparam['h'],
<install as="Horde/Image/Effect/Imagick/TextWatermark.php" name="lib/Horde/Image/Effect/Imagick/TextWatermark.php" />
<install as="Horde/Image/Effect/Imagick/Unsharpmask.php" name="lib/Horde/Image/Effect/Imagick/Unsharpmask.php" />
<install as="Horde/Image/Effect/Imagick/LiquidResize.php" name="lib/Horde/Image/Effect/Imagick/LiquidResize.php" />
- <isntall as="Horde/Image/Effect/Imagick/SmartCrop.php" name="lib/Horde/Image/Effect/Imagick/SmartCrop.php" />
+ <install as="Horde/Image/Effect/Imagick/SmartCrop.php" name="lib/Horde/Image/Effect/Imagick/SmartCrop.php" />
<install as="Horde/Image/Exif/Base.php" name="lib/Horde/Image/Exif/Base.php" />
<install as="Horde/Image/Exif/Bundled.php" name="lib/Horde/Image/Exif/Bundled.php" />
<install as="Horde/Image/Exif/Exiftool.php" name="lib/Horde/Image/Exif/Exiftool.php" />
// profiling.
$driver = Horde_Util::getFormData('driver', 'Im');
$test = Horde_Util::getFormData('test');
+
+// Don't use horde config since we might be configured for Imagick only.
$convert = trim(`which convert`);
$identify = trim(`which identify`);
+
$handler = new Horde_Log_Handler_Stream(fopen('/tmp/imagetest.log','a+'));
$logger = new Horde_Log_Logger($handler);
switch ($test) {
+case 'smart':
+ $time = xdebug_time_index();
+ $image = getImageObject(array('filename' => 'img4.jpg'));
+ $image->addEffect('SmartCrop', array('width' => 100, 'height' => 100));
+ $image->display();
+ $time = xdebug_time_index() - $time;
+ $memory = xdebug_peak_memory_usage();
+ logThis($test, $time, $memory);
+ exit;
+
case 'liquid':
$time = xdebug_time_index();
$image = getImageObject(array('filename' => 'img4.jpg'));
$image->addEffect('LiquidResize', array('ratio' => true, 'width' => 612, 'height' => 340, 'delta_x' => 3, 'rigidity' => 0));
$image->display();
- break;
+ $time = xdebug_time_index() - $time;
+ $memory = xdebug_peak_memory_usage();
+ logThis($test, $time, $memory);
+ exit;
case 'multipage':
$time = xdebug_time_index();
$first = false;
}
}
- logThis($test, $time, xdebug_peak_memory_usage());
+ $time = xdebug_time_index() - $time;
+ $memory = xdebug_peak_memory_usage();
+ logThis($test, $time, $memory);
case 'testInitialState':
// Solid blue background color - basically tests initial state of the
$context = array('tmpdir' => Horde::getTempDir(),
'convert' => $GLOBALS['convert'],
- 'logger' => $GLOBALS['logger'],
+ 'logger' => $GLOBALS['injector']->getInstance('Horde_Log_Logger'),
'identify' => $GLOBALS['identify']);
$params['context'] = $context;
+
return Horde_Image::factory($GLOBALS['driver'], $params);
}
'testResize' => 'Test resize method.',
'multipage' => 'Test Multipage tiffs',
'liquid' => 'Test Seam Carving',
+ 'smart' => 'Test Smart Crop (Center of Edginess)'
);
?>
<html>