How could I adjust the color levels of an image? I mean, like using Tools->Color Tools->Levels in gimp. I've tried with contrast, gamma and brightness, but it's not exactly the same. Colors get a little strange this way.
Maybe it's the same question as in this topic: http://galfar.vevb.net/imaging/smf/index.php/topic,81.0.html (http://galfar.vevb.net/imaging/smf/index.php/topic,81.0.html)
I could add new point transform to do the same thing as Levels.
Can you access SVN repository so you could check it out when it's done?
Wonderful! Just tell me and I'll try!
Check out the new canvas method AdjustColorLevels. You can set black, white, and mid point as in common image editors.
I must be doing something wrong. When I run this procedure, I get an Invalid floating point operation exception. Using ModifyContrastBrightness works ok.
var
FBitmap:TImagingBitmap;
FImage:TMultiImage;
FImageCanvas: TImagingCanvas;
begin
FImage:=TMultiImage.Create;
FBitmap:=TImagingBitmap.Create;
Image.Picture.Graphic:=FBitmap;
FImageCanvas:=TImagingCanvas.Create;
FImage.LoadFromFile('example.JPG');
Image.Picture.Graphic.Assign(FImage);
FImageCanvas.CreateForImage(FImage);
FImageCanvas.AdjustColorLevels(27.0,252.0,1.0);
Image.Picture.Graphic.Assign(FImage);
end;
Black and white point values must be in the range 0.0 to 1.0, not 0 to 255.
So just divide your points by 255 and you should get correct results.
All color values in the canvas class that are of Single type use [0,1] range.
Well, MidPoint, at least in The Gimp can be up to 10.0.
I get the same exception, but I have made some changes and now it runs great. The first one tries to do less operations, but I don't really know if I get that (every time I run the function it takes a different time).
procedure TImagingCanvas.AdjustColorLevels(BlackPoint, WhitePoint, MidPoint: Single);
begin
PointTransform(TransformLevels, BlackPoint, WhitePoint-BlackPoint, 1.0/MidPoint);
end;
function TransformLevels(const Pixel: TColorFPRec; BlackPoint, Divisor, Exponente: Single): TColorFPRec;
begin
Result.A := Pixel.A;
if Pixel.R>BlackPoint then
Result.R := Power((Pixel.R - BlackPoint) / Divisor, Exponente)
else
Result.R:=0.0;
if Pixel.G>BlackPoint then
Result.G := Power((Pixel.G - BlackPoint) / Divisor, Exponente)
else
Result.G:=0.0;
if Pixel.B>BlackPoint then
Result.B := Power((Pixel.B - BlackPoint) / Divisor, Exponente)
else
Result.B:=0.0;
end;
MidPoint could be > 1.0, it's gamma and not color value.
Could you upload/attach the image that caused AVs here?
It happened with any image. For example, the last image I was using was lazarus.jpg. You can find it in your lazarus installation, inside of components/jpeg/examples/.
The exception happened when Result was less than 0, so I just control its value, and in that case, assign 0 to this.
Didn't it happen to you?
Do you think calculating these parameters before calling the function could make it faster? As I said before, I don't get anything consistent.
Oh, I did all the tests in Deplhi and it worked there.
FPC compiled exe indeeds throws "Invalid FP operation" on many images.
Your fix helps, thanks.
I tried it in lazarus under linux (x86 and amd64) getting the errors I wrote before.