In Photoshop there is a feature called Auto Contrast.
It builds a histogram of the image and spreads out the values so the whole tonal-range is being used. This is very usefull for images that have been taken in bad lightning conditions or low-range cameras. Makes the images look a lot crispier.
PHPThumb has these two funktions:
function HistogramAnalysis(&$gdimg, $calculateGray=false) {
$ImageSX = ImageSX($gdimg);
$ImageSY = ImageSY($gdimg);
for ($x = 0; $x < $ImageSX; $x++) {
for ($y = 0; $y < $ImageSY; $y++) {
$OriginalPixel = phpthumb_functions::GetPixelColor($gdimg, $x, $y);
@$Analysis['red'][$OriginalPixel['red']]++;
@$Analysis['green'][$OriginalPixel['green']]++;
@$Analysis['blue'][$OriginalPixel['blue']]++;
@$Analysis['alpha'][$OriginalPixel['alpha']]++;
if ($calculateGray) {
$GrayPixel = phpthumb_functions::GrayscalePixel($OriginalPixel);
@$Analysis['gray'][$GrayPixel['red']]++;
}
}
}
$keys = array('red', 'green', 'blue', 'alpha');
if ($calculateGray) {
$keys[] = 'gray';
}
foreach ($keys as $dummy => $key) {
ksort($Analysis[$key]);
}
return $Analysis;
}and
function HistogramStretch(&$gdimg, $band='*', $method=0, $threshold=0.1) {
// equivalent of "Auto Contrast" in Adobe Photoshop
// method 0 stretches according to RGB colors. Gives a more conservative stretch.
// method 1 band stretches according to grayscale which is color-biased (59% green, 30% red, 11% blue). May give a punchier / more aggressive stretch, possibly appearing over-saturated
$Analysis = phpthumb_filters::HistogramAnalysis($gdimg, true);
$keys = array('r'=>'red', 'g'=>'green', 'b'=>'blue', 'a'=>'alpha', '*'=>(($method == 0) ? 'all' : 'gray'));
$band = substr($band, 0, 1);
if (!isset($keys[$band])) {
return false;
}
$key = $keys[$band];
// If the absolute brightest and darkest pixels are used then one random
// pixel in the image could throw off the whole system. Instead, count up/down
// from the limit and allow <threshold> (default = 0.1%) of brightest/darkest
// pixels to be clipped to min/max
$threshold = floatval($threshold) / 100;
$clip_threshold = ImageSX($gdimg) * ImageSX($gdimg) * $threshold;
//if ($min >= 0) {
// $range_min = min($min, 255);
//} else {
$countsum = 0;
for ($i = 0; $i <= 255; $i++) {
if ($method == 0) {
$countsum = max(@$Analysis['red'][$i], @$Analysis['green'][$i], @$Analysis['blue'][$i]);
} else {
$countsum += @$Analysis[$key][$i];
}
if ($countsum >= $clip_threshold) {
$range_min = $i - 1;
break;
}
}
$range_min = max($range_min, 0);
//}
//if ($max > 0) {
// $range_max = max($max, 255);
//} else {
$countsum = 0;
for ($i = 255; $i >= 0; $i--) {
if ($method == 0) {
$countsum = max(@$Analysis['red'][$i], @$Analysis['green'][$i], @$Analysis['blue'][$i]);
} else {
$countsum += @$Analysis[$key][$i];
}
if ($countsum >= $clip_threshold) {
$range_max = $i + 1;
break;
}
}
$range_max = min($range_max, 255);
//}
$range_scale = (($range_max == $range_min) ? 1 : (255 / ($range_max - $range_min)));
if (($range_min == 0) && ($range_max == 255)) {
// no adjustment neccesary - don't waste CPU time!
return true;
}
$ImageSX = ImageSX($gdimg);
$ImageSY = ImageSY($gdimg);
for ($x = 0; $x < $ImageSX; $x++) {
for ($y = 0; $y < $ImageSY; $y++) {
$OriginalPixel = phpthumb_functions::GetPixelColor($gdimg, $x, $y);
if ($band == '*') {
$new['red'] = min(255, max(0, ($OriginalPixel['red'] - $range_min) * $range_scale));
$new['green'] = min(255, max(0, ($OriginalPixel['green'] - $range_min) * $range_scale));
$new['blue'] = min(255, max(0, ($OriginalPixel['blue'] - $range_min) * $range_scale));
$new['alpha'] = min(255, max(0, ($OriginalPixel['alpha'] - $range_min) * $range_scale));
} else {
$new = $OriginalPixel;
$new[$key] = min(255, max(0, ($OriginalPixel[$key] - $range_min) * $range_scale));
}
$newColor = phpthumb_functions::ImageColorAllocateAlphaSafe($gdimg, $new['red'], $new['green'], $new['blue'], $new['alpha']);
ImageSetPixel($gdimg, $x, $y, $newColor);
}
}
return true;
}I'm a designer, so I can't make a module from that code. It seems though that it wouldn't be too hard to hard to do for someone who knows his/her way around.
Comments
Comment #1
dman commentedThanks for the code, I can see how it would fit in.
maybe one day...
Comment #2
stefan81 commentedHy, any progress on this?
Would be cool!
Comment #3
chaps555 commentedHello ,
I am not able to understand this function
HistogramAnalysis.
How the analysis is carried out here.
Chaps
Comment #4
millenniumtreeIf you're using imagemagick instead of GD, you can do the following:
Install imagecache_customactions module.
Add a custom action, and enter the following PHP code.
Cheers,
--tree
Comment #5
NoRandom commentedHi, I've used Imagemagick in the past from commandline to alter images but this is my first time trying to use it from PHP. Where can I find information of the functions or methods available for $image?
Following the example from millenniumtree I've tried:
...and it seems to work. But, when I want a harder contrast this doesn't work:
By the way, in Drupal 7 you don't have to return the image at the end.
Comment #6
fietserwin1st: let's move requests to the D7 branch. Our D6 branch is in maintenance only now.
#5: According to the documentation -contrast has no parameter, though you can use it with -contrast and +contrast (more/less contrast) and you can repeat the command. See: http://www.imagemagick.org/script/command-line-options.php#contrast.