Thanks in advance.
José Eduardo
Brightness is easy. Just add a fixed value to each of the color components
(with any value going over 255 being set to 255).
ie, to brighten a color:
c = the pixel's color
r = getrvalue( c) + 40
g = getgvalue( c) + 40
b = getbvalue( c) + 40
if r > 255 then r = 255...
if r < 0 then r = 0
etc
then set the pixel to that color
It seems counter-intuitive at first to add a fixed value to each, but it
actually looks better than multiplying each component by a
brightness/darkening factor.
I've never done contrast, so someone else will have to chime in with that.
Here's some code ... that might give you an idea ... there are probably
faster examples / libraries ... and you need to do some basic checks on the
bitmap like testing that the bitmap height or width aren't zero ... depends
on what you're doing.
If you want lots of other bitmap graphic effects then take a look at janFX
at :
http://jansfreeware.com/janfx.zip
Andrew
type
TRGBArray = array[0..0] of TRGBTriple;
pRGBArray = ^TRGBArray;
function IntToByte(i : integer) : byte;
begin
if (i > 255) then
Result := 255
else if (i < 0) then
Result := 0
else
Result := i;
end;
{--------------------------------------------------------------------------------------------------}
procedure Brightness(Src : TBitmap; Amount : integer);
var
x, y : integer;
SrcLine : pRGBArray;
SrcGap : integer;
begin
Src.PixelFormat := pf24bit;
SrcLine := Src.ScanLine[0];
SrcGap := Integer(Src.ScanLine[1]) - Integer(SrcLine);
{$ifopt R+} {$define RangeCheck} {$endif} {$R-}
for y := 0 to pred(Src.Height) do begin
for x := 0 to pred(Src.Width) do begin
SrcLine[x].rgbtRed := IntToByte(SrcLine[x].rgbtRed +
MulDiv(SrcLine[x].rgbtRed, Amount, 100));
SrcLine[x].rgbtGreen := IntToByte(SrcLine[x].rgbtGreen +
MulDiv(SrcLine[x].rgbtGreen, Amount, 100));
SrcLine[x].rgbtBlue := IntToByte(SrcLine[x].rgbtBlue +
MulDiv(SrcLine[x].rgbtBlue, Amount, 100));
end; {for}
SrcLine := pRGBArray(Integer(SrcLine) + SrcGap);
end; {for}
{$ifdef RangeCheck} {$R+} {$undef RangeCheck} {$endif}
end; {Brightness}
{--------------------------------------------------------------------------------------------------}
procedure Contrast(Src : TBitmap; Amount : integer);
var
x, y : integer;
r, g, b : integer;
rr, gg, bb : integer;
SrcLine : pRGBArray;
SrcGap : integer;
begin
Src.PixelFormat := pf24bit;
SrcLine := Src.ScanLine[0];
SrcGap := Integer(Src.ScanLine[1]) - Integer(SrcLine);
{$ifopt R+} {$define RangeCheck} {$endif} {$R-}
for y := 0 to pred(Src.Height) do begin
for x := 0 to pred(Src.Width) do begin
r := SrcLine[x].rgbtRed;
g := SrcLine[x].rgbtGreen;
b := SrcLine[x].rgbtBlue;
rr := MulDiv(abs(127-r), Amount, 100);
gg := MulDiv(abs(127-g), Amount, 100);
bb := MulDiv(abs(127-b), Amount, 100);
if (r > 127) then
r := r+rr
else
r := r-rr;
if (g > 127) then
g := g+gg
else
g := g-gg;
if (b > 127) then
b := b+bb
else
b := b-bb;
SrcLine[x].rgbtRed := IntToByte(r);
SrcLine[x].rgbtGreen := IntToByte(g);
SrcLine[x].rgbtBlue := IntToByte(b);
end; {for}
SrcLine := pRGBArray(Integer(SrcLine) + SrcGap);
end; {for}
{$ifdef RangeCheck} {$R+} {$undef RangeCheck} {$endif}
end; {Contrast}
{--------------------------------------------------------------------------------------------------}
Look at http://www.efg2.com/ , you'll find everything you want at there.
Using it at the start point. Good luck!
Best regards.
Xiaoguang
"Andrew Jameson" <softspots...@SPAMgmail.com> escreveu na mensagem
news:47607992$1...@newsgroups.borland.com...
So something like this:
procedure AdjustContrastAndBrightness(ABitmap: TBitmap; AContrast,
ABrightness: integer);
// AContrast given as a percentage adjustment
var
Map: array[0..255] of byte;
Stride: integer;
PS, P: Pbyte;
function Clamp(V: integer): integer;
begin
if V < 0 then
Result := 0
else
if V > 255 then
Result := 255
else
Result := V;
end;
begin
// First setup map
for i := 0 to 255 do
Map[i] := Clamp(round((i - 127) * AContrast / 100) + 127 + ABrightness);
// Make sure we have 24bit colors
ABitmap.PixelFormat := pf24bit;
// Width, Height, Scanstride
W := ABitmap.Width;
H := ABitmap.Height;
if H = 0 then exit;
Stride := 0;
if H >= 2 then
Stride := integer(ABitmap.ScanLine[1]) - integer(ABitmap.ScanLine[0]);
// PS points to current scanline
PS := ABitmap.ScanLine[0];
for y := 0 to H - 1 do
begin
P := PS;
for x := 0 to W * 3 - 1 do
begin
P^ := Map[P^];
inc(P);
end;
inc(PS, Stride);
end;
end;
Hope that helps,
Nils
www.simdesign.nl
"José Eduardo" <zeduar...@ig.com.br> schreef in bericht
news:4761...@newsgroups.borland.com...
Thanks for that Nils,
I always had that nagging feeling that I was missing some optimization ...
it's obvious when someone else shows you !
Andrew