Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

How to adjust brightness/contrast of a bitmap?

295 views
Skip to first unread message

José Eduardo

unread,
Dec 12, 2007, 1:38:20 PM12/12/07
to
Hi, i´m completly newbee to imageProcessing and i would like to know
how to adjust the brightness and contrast of a image defined by a TBitmap.

Thanks in advance.
José Eduardo

GrandmasterB

unread,
Dec 12, 2007, 4:33:24 PM12/12/07
to
"José Eduardo" <zeduar...@ig.com.br> wrote in message
news:4760...@newsgroups.borland.com...

> Hi, i´m completly newbee to imageProcessing and i would like to know
> how to adjust the brightness and contrast of a image defined by a TBitmap.

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.


Andrew Jameson

unread,
Dec 12, 2007, 7:15:52 PM12/12/07
to

"José Eduardo" <zeduar...@ig.com.br> wrote in message
news:4760...@newsgroups.borland.com...
> Hi, i´m completly newbee to imageProcessing and i would like to know
> how to adjust the brightness and contrast of a image defined by a TBitmap.

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}

{--------------------------------------------------------------------------------------------------}


Ma Xiaoguang

unread,
Dec 12, 2007, 8:00:36 PM12/12/07
to
Hi,

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


José Eduardo

unread,
Dec 13, 2007, 6:06:46 AM12/13/07
to
GrandmasterB, Andrew, and Xiaoguang
Thanks again...

"Andrew Jameson" <softspots...@SPAMgmail.com> escreveu na mensagem
news:47607992$1...@newsgroups.borland.com...

Nils Haeck

unread,
Dec 16, 2007, 5:31:03 AM12/16/07
to
A much faster option is to first create a table with entries 0..255,
corresponding to current value and holding the new values, then apply this
in a loop to all the pixel components. This avoids the muldiv inside the
loop (which is very slow).

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...

Andrew Jameson

unread,
Dec 16, 2007, 10:18:42 AM12/16/07
to
"Nils Haeck" <b...@bla.com> wrote in message
news:4764...@newsgroups.borland.com...

>A much faster option is to first create a table with entries 0..255,
>corresponding to current value and holding the new values, then apply this
>in a loop to all the pixel components. This avoids the muldiv inside the
>loop (which is very slow).

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


0 new messages