| 1 |
<?php // $Id: imageapi_gd.module,v 1.16 2009/02/13 02:29:01 drewish Exp $
|
| 2 |
|
| 3 |
/**
|
| 4 |
* @file
|
| 5 |
* GD2 toolkit functions
|
| 6 |
*/
|
| 7 |
|
| 8 |
function imageapi_gd_image_sharpen(stdImage $image, $radius, $sigma, $amount, $threshold) {
|
| 9 |
$threshold = round($threshold * 255);
|
| 10 |
$image->resource = imageapi_gd_unsharp_mask($image->resource, $radius, $sigma, $amount, $threshold);
|
| 11 |
return TRUE;
|
| 12 |
}
|
| 13 |
|
| 14 |
// Provide a implementation of imagerotate() and imagefilter() if they
|
| 15 |
// weren't compiled into PHP.
|
| 16 |
if (!function_exists('imagerotate')) {
|
| 17 |
require_once drupal_get_path('module', 'imageapi') .'/imagerotate.inc';
|
| 18 |
}
|
| 19 |
if (!function_exists('imagefilter')) {
|
| 20 |
require_once drupal_get_path('module', 'imageapi') .'/imagefilter.inc';
|
| 21 |
}
|
| 22 |
|
| 23 |
/**
|
| 24 |
* $sigma is currently unused for _gd_sharp_mask due to 3x3 convolution matrix limit.
|
| 25 |
* we should explore properly implementing sigma.
|
| 26 |
*/
|
| 27 |
function imageapi_gd_unsharp_mask($img, $radius, $sigma, $amount, $threshold) {
|
| 28 |
|
| 29 |
//////////////////////////////////////////////////////////////
|
| 30 |
////
|
| 31 |
//// Unsharp Mask for PHP - version 2.1.1
|
| 32 |
////
|
| 33 |
//// Unsharp mask algorithm by Torstein H�nsi 2003-07.
|
| 34 |
//// thoensi_at_netcom_dot_no.
|
| 35 |
//// Please leave this notice.
|
| 36 |
////
|
| 37 |
//////////////////////////////////////////////////////////////
|
| 38 |
|
| 39 |
// http://vikjavev.no/computing/ump.php
|
| 40 |
|
| 41 |
// $img is an image that is already created within php using
|
| 42 |
// imgcreatetruecolor. No url! $img must be a truecolor image.
|
| 43 |
|
| 44 |
// Attempt to calibrate the parameters to Photoshop:
|
| 45 |
if ($amount > 500) $amount = 500;
|
| 46 |
$amount = $amount * 0.016;
|
| 47 |
if ($radius > 50) $radius = 50;
|
| 48 |
$radius = $radius * 2;
|
| 49 |
if ($threshold > 255) $threshold = 255;
|
| 50 |
|
| 51 |
$radius = abs(round($radius)); // Only integers make sense.
|
| 52 |
if ($radius == 0) {
|
| 53 |
return $img; imagedestroy($img);
|
| 54 |
break;
|
| 55 |
}
|
| 56 |
|
| 57 |
$w = imagesx($img); $h = imagesy($img);
|
| 58 |
$img_canvas = imagecreatetruecolor($w, $h);
|
| 59 |
$img_blur = imagecreatetruecolor($w, $h);
|
| 60 |
|
| 61 |
// Gaussian blur matrix:
|
| 62 |
//
|
| 63 |
// 1 2 1
|
| 64 |
// 2 4 2
|
| 65 |
// 1 2 1
|
| 66 |
//
|
| 67 |
//////////////////////////////////////////////////
|
| 68 |
|
| 69 |
$matrix = array(
|
| 70 |
array( 1, 2, 1 ),
|
| 71 |
array( 2, 4, 2 ),
|
| 72 |
array( 1, 2, 1 )
|
| 73 |
);
|
| 74 |
|
| 75 |
imagecopy($img_blur, $img, 0, 0, 0, 0, $w, $h);
|
| 76 |
imageconvolution($img_blur, $matrix, 16, 0);
|
| 77 |
|
| 78 |
if ($threshold > 0) {
|
| 79 |
// Calculate the difference between the blurred pixels and the original
|
| 80 |
// and set the pixels
|
| 81 |
for ($x = 0; $x < $w-1; $x++) { // each row
|
| 82 |
for ($y = 0; $y < $h; $y++) { // each pixel
|
| 83 |
|
| 84 |
$rgb_orig = imagecolorat($img, $x, $y);
|
| 85 |
$r_orig = (($rgb_orig >> 16) & 0xFF);
|
| 86 |
$g_orig = (($rgb_orig >> 8) & 0xFF);
|
| 87 |
$b_orig = ($rgb_orig & 0xFF);
|
| 88 |
|
| 89 |
$rgb_blur = imagecolorat($img_blur, $x, $y);
|
| 90 |
|
| 91 |
$r_blur = (($rgb_blur >> 16) & 0xFF);
|
| 92 |
$g_blur = (($rgb_blur >> 8) & 0xFF);
|
| 93 |
$b_blur = ($rgb_blur & 0xFF);
|
| 94 |
|
| 95 |
// When the masked pixels differ less from the original
|
| 96 |
// than the threshold specifies, they are set to their original value.
|
| 97 |
$r_new = (abs($r_orig - $r_blur) >= $threshold)
|
| 98 |
? max(0, min(255, ($amount * ($r_orig - $r_blur)) + $r_orig))
|
| 99 |
: $r_orig;
|
| 100 |
$g_new = (abs($g_orig - $g_blur) >= $threshold)
|
| 101 |
? max(0, min(255, ($amount * ($g_orig - $g_blur)) + $g_orig))
|
| 102 |
: $g_orig;
|
| 103 |
$b_new = (abs($b_orig - $b_blur) >= $threshold)
|
| 104 |
? max(0, min(255, ($amount * ($b_orig - $b_blur)) + $b_orig))
|
| 105 |
: $b_orig;
|
| 106 |
|
| 107 |
if (($r_orig != $r_new) || ($g_orig != $g_new) || ($b_orig != $b_new)) {
|
| 108 |
$pix_col = imagecolorallocate($img, $r_new, $g_new, $b_new);
|
| 109 |
imagesetpixel($img, $x, $y, $pix_col);
|
| 110 |
}
|
| 111 |
}
|
| 112 |
}
|
| 113 |
}
|
| 114 |
else{
|
| 115 |
for ($x = 0; $x < $w; $x++) { // each row
|
| 116 |
for ($y = 0; $y < $h; $y++) { // each pixel
|
| 117 |
$rgb_orig = imagecolorat($img, $x, $y);
|
| 118 |
$r_orig = (($rgb_orig >> 16) & 0xFF);
|
| 119 |
$g_orig = (($rgb_orig >> 8) & 0xFF);
|
| 120 |
$b_orig = ($rgb_orig & 0xFF);
|
| 121 |
|
| 122 |
$rgb_blur = imagecolorat($img_blur, $x, $y);
|
| 123 |
|
| 124 |
$r_blur = (($rgb_blur >> 16) & 0xFF);
|
| 125 |
$g_blur = (($rgb_blur >> 8) & 0xFF);
|
| 126 |
$b_blur = ($rgb_blur & 0xFF);
|
| 127 |
|
| 128 |
$r_new = ($amount * ($r_orig - $r_blur)) + $r_orig;
|
| 129 |
if ($r_new>255) $r_new=255;
|
| 130 |
elseif ($r_new<0) $r_new=0;
|
| 131 |
|
| 132 |
$g_new = ($amount * ($g_orig - $g_blur)) + $g_orig;
|
| 133 |
if ($g_new>255) $g_new=255;
|
| 134 |
elseif ($g_new<0) $g_new=0;
|
| 135 |
|
| 136 |
$b_new = ($amount * ($b_orig - $b_blur)) + $b_orig;
|
| 137 |
if ($b_new>255) $b_new=255;
|
| 138 |
elseif ($b_new<0) $b_new=0;
|
| 139 |
|
| 140 |
$rgb_new = ($r_new << 16) + ($g_new <<8) + $b_new;
|
| 141 |
imagesetpixel($img, $x, $y, $rgb_new);
|
| 142 |
}
|
| 143 |
}
|
| 144 |
}
|
| 145 |
imagedestroy($img_canvas);
|
| 146 |
imagedestroy($img_blur);
|
| 147 |
|
| 148 |
return $img;
|
| 149 |
}
|