Hi, the image I'm working with is of a person, so I've grabbed an image of a sunflower and run it through the same process. The difference between the two corrected images is fairly clear.
The original image is:
The GIMP corrected image is:
The IM corrected image is:
In GIMP I apply +50 to the Red channel in Shadows, Midtones and Highlights to get this effect. In the color balance screen in GIMP there is a "Preserve Luminosity" checkbox which I also uncheck.
In Magick I'm using .Evaluate as below. It's a bit clunky, but I think it's okay. I want to try and use an overload which accepts midpoint so that I can adjust each channel for each range. I can't work out which midpoints to use, though. I've seen a post about
ImageMagick which suggests
Low = (mean  factor * std. dev.
Mid = mean
High = mean + factor * std. dev.
img.Evaluate(
ImageMagick.Channels.Red,
settings.Red < 0 ? ImageMagick.EvaluateOperator.Subtract : ImageMagick.EvaluateOperator.Add,
settings.Red < 0 ? settings.Red * 1 : settings.Red
);
One other thing I've noticed; thinking about how to calculate the midpoint of the range to apply the change to, I started looking at the statistics that IM generates. For the corrected image shown in this post GIMP (on the Red channel) gave me a Mean of 191.4
and a St. Dev. of 54.9. IM gives a mean of 203.1, st. dev. of 30908 and variance of 1.277 * 10^313. These are just wrong.
I've written my own quick and dirty class to generate statistics from the PixelCollection that IM gives me and I get the same values as GIMP. Not sure this actually makes a difference, but its worth noting.
var imStats = img.Statistics();
var myStats = new Statistics(img.GetReadOnlyPixels());
public class Statistics
{
public double StDev = 0.0;
public double Variance = 0.0;
public double Mean = 0;
public Int32 PixelCount = 0;
public Statistics(ImageMagick.PixelCollection pixels)
{
var pixelEnumerator = pixels.GetEnumerator();
double mean = 0.0;
double variance = 0.0;
int n = 0;
int total = 0;
while (pixelEnumerator.MoveNext())
{
total += Convert.ToInt32(pixelEnumerator.Current.ToColor().R);
n++;
}
mean = total / n;
pixelEnumerator.Reset();
while (pixelEnumerator.MoveNext())
{
variance += Math.Pow((Convert.ToDouble(pixelEnumerator.Current.ToColor().R)  Convert.ToDouble(mean)), 2);
}
Variance = variance / total;
StDev = Math.Sqrt(variance);
PixelCount = total;
Mean = mean;
}
}
