diff options
author | rvelices <rv-github@modusoptimus.com> | 2012-01-05 21:35:25 +0000 |
---|---|---|
committer | rvelices <rv-github@modusoptimus.com> | 2012-01-05 21:35:25 +0000 |
commit | e64ab974df242b25ade46d9795294ae859060355 (patch) | |
tree | 87c98fb3c4f7e0cd4318744edef74f4507be5482 /admin | |
parent | 19b58d483bf3c8de06e6b494040cda6ce446bec2 (diff) |
feature 2548 multisize - sharpen + watermarks (partially implemented / no test with imagick extension)
git-svn-id: http://piwigo.org/svn/trunk@12851 68402e56-0260-453c-a942-63ccdbb3a9ee
Diffstat (limited to 'admin')
-rw-r--r-- | admin/derivatives.php | 97 | ||||
-rw-r--r-- | admin/include/image.class.php | 104 | ||||
-rw-r--r-- | admin/themes/default/template/derivatives.tpl | 61 |
3 files changed, 255 insertions, 7 deletions
diff --git a/admin/derivatives.php b/admin/derivatives.php index fbf1ccffb..fde3e0db3 100644 --- a/admin/derivatives.php +++ b/admin/derivatives.php @@ -28,6 +28,7 @@ $errors = array(); if ( isset($_POST['d']) ) { $pderivatives = $_POST['d']; + $pwatermark = $_POST['w']; // step 1 - sanitize HTML input foreach($pderivatives as $type => &$pderivative) @@ -86,10 +87,55 @@ if ( isset($_POST['d']) ) $prev_w = intval($pderivative['w']); $prev_h = intval($pderivative['h']); } + + $v = intval($pderivative['sharpen']); + if ($v<0 || $v>100) + { + $errors[$type]['sharpen'] = '[0..100]'; + } + $v = intval($pderivative['quality']); + if ($v<=0 || $v>100) + { + $errors[$type]['quality'] = '(0..100]'; + } + } + $v = intval($pwatermark['xpos']); + if ($v<0 || $v>100) + { + $errors['watermark']['xpos'] = '[0..100]'; } + $v = intval($pwatermark['ypos']); + if ($v<0 || $v>100) + { + $errors['watermark']['ypos'] = '[0..100]'; + } + $v = intval($pwatermark['opacity']); + if ($v<=0 || $v>100) + { + $errors['watermark']['opacity'] = '(0..100]'; + } + + // step 3 - save data if (count($errors)==0) { + $watermark = new WatermarkParams(); + $watermark->file = $pwatermark['file']; + $watermark->xpos = intval($pwatermark['xpos']); + $watermark->ypos = intval($pwatermark['ypos']); + $watermark->xrepeat = intval($pwatermark['xrepeat']); + $watermark->opacity = intval($pwatermark['opacity']); + $watermark->min_size = array(intval($pwatermark['minw']),intval($pwatermark['minh'])); + + $old_watermark = ImageStdParams::get_watermark(); + $watermark_changed = + $watermark->file != $old_watermark->file + || $watermark->xpos != $old_watermark->xpos + || $watermark->ypos != $old_watermark->ypos + || $watermark->xrepeat != $old_watermark->xrepeat + || $watermark->opacity != $old_watermark->opacity; + ImageStdParams::set_watermark($watermark); + $enabled = ImageStdParams::get_defined_type_map(); $disabled = @unserialize( @$conf['disabled_derivatives'] ); if ($disabled===false) @@ -106,11 +152,15 @@ if ( isset($_POST['d']) ) { $new_params = new DerivativeParams( new SizingParams( - array($pderivative['w'],$pderivative['h']), + array(intval($pderivative['w']), intval($pderivative['h'])), round($pderivative['crop'] / 100, 2), - array($pderivative['minw'],$pderivative['minh']) + array(intval($pderivative['minw']), intval($pderivative['minh'])) ) ); + $new_params->sharpen = intval($pderivative['sharpen']); + $new_params->quality = intval($pderivative['quality']); + ImageStdParams::apply_global($new_params); + if (isset($enabled[$type])) { $old_params = $enabled[$type]; @@ -126,6 +176,22 @@ if ( isset($_POST['d']) ) { $same = false; } + + if ( $same && + ( $new_params->sharpen != $old_params->sharpen + || $new_params->quality > $old_params->quality) + ) + { + $same = false; + } + + if ($same && + ( $new_params->use_watermark != $old_params->use_watermark + || $new_params->use_watermark && $watermark_changed ) + ) + { + $same = false; + } if (!$same) { @@ -182,6 +248,7 @@ if ( isset($_POST['d']) ) else { $template->assign('derivatives', $pderivatives); + $template->assign('watermark', $pwatermark); $template->assign('ferrors', $errors); } } @@ -224,11 +291,37 @@ if (count($errors)==0) { $tpl_var['minw'] = $tpl_var['minh'] = ""; } + $tpl_var['sharpen'] = $params->sharpen; + $tpl_var['quality'] = $params->quality; } $tpl_vars[$type]=$tpl_var; } $template->assign('derivatives', $tpl_vars); + + $wm = ImageStdParams::get_watermark(); + $template->assign('watermark', array( + 'file' => $wm->file, + 'minw' => $wm->min_size[0], + 'minh' => $wm->min_size[1], + 'xpos' => $wm->xpos, + 'ypos' => $wm->ypos, + 'xrepeat' => $wm->xrepeat, + 'opacity' => $wm->opacity, + )); +} + +$watermark_files = array(); +foreach (glob(PHPWG_ROOT_PATH.'themes/default/watermarks/*.png') as $file) +{ + $watermark_files[] = substr($file, strlen(PHPWG_ROOT_PATH)); +} +$watermark_filemap = array( '' => '---' ); +foreach( $watermark_files as $file) +{ + $display = basename($file); + $watermark_filemap[$file] = $display; } +$template->assign('watermark_files', $watermark_filemap); $template->set_filename('derivatives', 'derivatives.tpl'); $template->assign_var_from_handle('ADMIN_CONTENT', 'derivatives'); diff --git a/admin/include/image.class.php b/admin/include/image.class.php index 53a27b924..03cf419a4 100644 --- a/admin/include/image.class.php +++ b/admin/include/image.class.php @@ -41,6 +41,10 @@ interface imageInterface function rotate($rotation); function resize($width, $height); + + function sharpen($amount); + + function compose($overlay, $x, $y, $opacity); function write($destination_filepath); } @@ -258,6 +262,31 @@ class pwg_image return $rotation; } + /** Returns a normalized convolution kernel for sharpening*/ + static function get_sharpen_matrix($amount) + { + // Amount should be in the range of 18-10 + $amount = round(abs(-18 + ($amount * 0.08)), 2); + + $matrix = array + ( + array(-1, -1, -1), + array(-1, $amount, -1), + array(-1, -1, -1), + ); + + $norm = array_sum(array_map('array_sum', $matrix)); + + for ($i=0; $i<3; $i++) + { + $line = & $matrix[$i]; + for ($j=0; $j<3; $j++) + $line[$j] /= $norm; + } + + return $matrix; + } + private function get_resize_result($destination_filepath, $width, $height, $time=null) { return array( @@ -397,6 +426,18 @@ class image_imagick implements imageInterface return $this->image->resizeImage($width, $height, Imagick::FILTER_LANCZOS, 0.9); } + function sharpen($amount) + { + $m = pwg_image::get_sharpen_matrix($amount); + return $this->image->convolveImage($m); + } + + function compose($overlay, $x, $y, $opacity) + { + // todo + return false; + } + function write($destination_filepath) { return $this->image->writeImage($destination_filepath); @@ -415,16 +456,17 @@ class image_ext_imagick implements imageInterface var $height = ''; var $commands = array(); - function __construct($source_filepath, $imagickdir='') + function __construct($source_filepath) { + global $conf; $this->source_filepath = $source_filepath; - $this->imagickdir = $imagickdir; + $this->imagickdir = $conf['ext_imagick_dir']; - $command = $imagickdir.'identify -format "%wx%h" "'.realpath($source_filepath).'"'; + $command = $this->imagickdir.'identify -format "%wx%h" "'.realpath($source_filepath).'"'; @exec($command, $returnarray); if(!is_array($returnarray) or empty($returnarray[0]) or !preg_match('/^(\d+)x(\d+)$/', $returnarray[0], $match)) { - die("[External ImageMagick] Corrupt image"); + die("[External ImageMagick] Corrupt image\n" . var_export($returnarray, true)); } $this->width = $match[1]; @@ -479,6 +521,31 @@ class image_ext_imagick implements imageInterface return true; } + function sharpen($amount) + { + $m = pwg_image::get_sharpen_matrix($amount); + + $param ='convolve "'.count($m).':'; + foreach ($m as $line) + { + $param .= ' '; + $param .= implode(',', $line); + } + $param .= '"'; + $this->add_command('morphology', $param); + return true; + } + + function compose($overlay, $x, $y, $opacity) + { + $param = 'compose dissolve -define compose:args='.$opacity; + $param .= ' '.escapeshellarg(realpath($overlay->image->source_filepath)); + $param .= ' -gravity NorthWest -geometry +'.$x.'+'.$y; + $param .= ' -composite'; + $this->add_command($param); + return true; + } + function write($destination_filepath) { $exec = $this->imagickdir.'convert'; @@ -496,6 +563,8 @@ class image_ext_imagick implements imageInterface $dest = pathinfo($destination_filepath); $exec .= ' "'.realpath($dest['dirname']).'/'.$dest['basename'].'"'; @exec($exec, $returnarray); + + //echo($exec); return is_array($returnarray); } } @@ -611,6 +680,33 @@ class image_gd implements imageInterface return $result; } + function sharpen($amount) + { + $m = pwg_image::get_sharpen_matrix($amount); + return imageconvolution($this->image, $m, 1, 0); + } + + function compose($overlay, $x, $y, $opacity) + { + $ioverlay = $overlay->image->image; + /* A replacement for php's imagecopymerge() function that supports the alpha channel + See php bug #23815: http://bugs.php.net/bug.php?id=23815 */ + + $ow = imagesx($ioverlay); + $oh = imagesy($ioverlay); + + // Create a new blank image the site of our source image + $cut = imagecreatetruecolor($ow, $oh); + + // Copy the blank image into the destination image where the source goes + imagecopy($cut, $this->image, 0, 0, $x, $y, $ow, $oh); + + // Place the source image in the destination image + imagecopy($cut, $ioverlay, 0, 0, 0, 0, $ow, $oh); + imagecopymerge($this->image, $cut, $x, $y, 0, 0, $ow, $oh, $opacity); + return true; + } + function write($destination_filepath) { $extension = strtolower(get_extension($destination_filepath)); diff --git a/admin/themes/default/template/derivatives.tpl b/admin/themes/default/template/derivatives.tpl index e0796024b..59f6344a7 100644 --- a/admin/themes/default/template/derivatives.tpl +++ b/admin/themes/default/template/derivatives.tpl @@ -23,6 +23,42 @@ {/literal}{/html_head} <form method="post" id="derviativesForm"> +<fieldset> +<legend>{'Watermark'|@translate}</legend> + + +<select name="w[file]" id="wSelect"> + {html_options options=$watermark_files selected=$watermark.file} +</select> + +<p><img id="wImg"></img></p> + +<label>{'Min Width'|@translate} + <input type="text" name="w[minw]" value="{$watermark.minw}"{if isset($ferrors.watermark.minw)}class="dError"{/if}> +</label> + +<label>{'Min Height'|@translate} + <input type="text" name="w[minh]" value="{$watermark.minh}"{if isset($ferrors.watermark.minh)}class="dError"{/if}> +</label> + +<label>{'X Position'|@translate} + <input type="text" name="w[xpos]" value="{$watermark.xpos}"{if isset($ferrors.watermark.xpos)}class="dError"{/if}> +%</label> + +<label>{'Y Position'|@translate} + <input type="text" name="w[ypos]" value="{$watermark.ypos}"{if isset($ferrors.watermark.ypos)}class="dError"{/if}> +%</label> + +<label>{'X Repeat'|@translate} + <input type="text" name="w[xrepeat]" value="{$watermark.xrepeat}"{if isset($ferrors.watermark.xrepeat)}class="dError"{/if}> +</label> + +<label>{'Opacity'|@translate} + <input type="text" name="w[opacity]" value="{$watermark.opacity}"{if isset($ferrors.watermark.opacity)}class="dError"{/if}> +</label> + +</fieldset> + <table class="table2"> <thead> <tr> @@ -33,6 +69,8 @@ <td>{'Crop'|@translate} (%)</td> <td>{'Min Width'|@translate}</td> <td>{'Min Height'|@translate}</td> + <td>{'Sharpen'|@translate} (%)</td> + <td>{'Quality'|@translate} (%)</td> </tr> </thead> {foreach from=$derivatives item=d key=type} @@ -65,7 +103,14 @@ <input type="text" name="d[{$type}][minh]" value="{$d.minh}"{if isset($ferrors.$type.minh)}class="dError"{/if}> {if isset($ferrors.$type.minh)}<span class="dErrorDesc" title="{$ferrors.$type.minh}">!</span>{/if} {/if}</td> - + <td> + <input type="text" name="d[{$type}][sharpen]" value="{$d.sharpen}"{if isset($ferrors.$type.sharpen)}class="dError"{/if}> + {if isset($ferrors.$type.sharpen)}<span class="dErrorDesc" title="{$ferrors.$type.sharpen}">!</span>{/if} + </td> + <td> + <input type="text" name="d[{$type}][quality]" value="{$d.quality}"{if isset($ferrors.$type.quality)}class="dError"{/if}> + {if isset($ferrors.$type.quality)}<span class="dErrorDesc" title="{$ferrors.$type.quality}">!</span>{/if} + </td> </tr> {/foreach} </table> @@ -76,4 +121,18 @@ jQuery(".dError").bind("focus", function () { jQuery(this).removeClass("dError"); } ); + +function onWatermarkChange() +{ + var val = jQuery("#wSelect").val(); + if (val.length) { + jQuery("#wImg").attr('src', {/literal}'{$ROOT_URL}'{literal}+val).show(); + } + else { + jQuery("#wImg").hide(); + } +} + +onWatermarkChange(); +jQuery("#wSelect").bind("change", onWatermarkChange ); {/literal}{/footer_script}
\ No newline at end of file |