Bookstore

 Computer Math and Games in Pascal (preview) Lazarus Handbook

Author Topic: [Solved] fast code to lower an image brightness  (Read 420 times)

the_magik_mushroom

• Newbie
• Posts: 4
[Solved] fast code to lower an image brightness
« on: March 12, 2023, 04:13:27 pm »
hey guys,
I'm trying to port this code from delphi to lazarus but it's not working :

Code: Pascal  [Select][+][-]
1. function IntToByte(i:Integer):Byte;
2. begin
3.   if      i>255 then Result:=255
4.   else if i<0   then Result:=0
5.   else               Result:=i;
6. end;
7.
8. procedure Darkness(var src: TBitmap; Amount: integer);
9. var
10.   p0: PByte;
11.   r, g, b, x, y: Integer;
12. begin
13.   src.PixelFormat := pf24bit;
14.   for y := 0 to src.Height - 1 do
15.   begin
16.     p0 := src.ScanLine[y];
17.     for x := 0 to src.Width - 1 do
18.     begin
19.       r := p0[x * 3];
20.       g := p0[x * 3 + 1];
21.       b := p0[x * 3 + 2];
22.       p0[x * 3] := IntToByte(r - ((r * Amount) div 255));
23.       p0[x * 3 + 1] := IntToByte(g - ((g * Amount) div 255));
24.       p0[x * 3 + 2] := IntToByte(b - ((b * Amount) div 255));
25.     end;
26.   end;
27. end;

what I want is to reduce the brightness of of bitmap, the code must be fast.
nothing happen when I try to use it on a TBitmap: Darkness(bmp,75);
any idea why?

thanks
« Last Edit: March 12, 2023, 08:10:19 pm by the_magik_mushroom »

Blaazen

• Hero Member
• Posts: 3234
• POKE 54296,15
Re: fast code to lower an image brightness
« Reply #1 on: March 12, 2023, 05:22:41 pm »
Hi,

I tested your code and it writes me: Warning: Symbol "Scanline" is not portable
So I jumped to source (Graphics.pp) via Alt+ArrowUp and there is a comment by the Scanline property: // Use only when wrpped by a begin/endupdate

So I added it to your code:
Code: Pascal  [Select][+][-]
1.   src.BeginUpdate(False);
2.   //all the code of the Darkness
3.   src.EndUpdate(True);
and it works.

When it comes to speed, this kind of graphics will always be rather slow.
Anyway div is a slow operation, you can try bitshift instead (but you will have not fine control).
You can also ommit conversion IntToByte, because it will never go over 255 and beyond 0.
Code: Pascal  [Select][+][-]
1. p0[x * 3] := (r - (r shr 3));

Lazarus 2.3.0 (rev main-2_3-2863...) FPC 3.3.1 x86_64-linux-qt Chakra, Qt 4.8.7/5.13.2, Plasma 5.17.3
Lazarus 1.8.2 r57369 FPC 3.0.4 i386-win32-win32/win64 Wine 3.21

Try Eye-Candy Controls: https://sourceforge.net/projects/eccontrols/files/

GetMem

• Hero Member
• Posts: 4074
Re: fast code to lower an image brightness
« Reply #2 on: March 12, 2023, 05:47:25 pm »
If speed is an issue, you can always switch to BGRABitmap:
1. Install BGRABitamp from OPM

Jorg3000

• Jr. Member
• Posts: 51
Re: fast code to lower an image brightness
« Reply #3 on: March 12, 2023, 08:02:48 pm »
Not testet!
Avoid all the x*3
Replace div 255 by shr 8 (= div 256)
Code: Pascal  [Select][+][-]
1. r := p0^;  // p0[0]
2. g := p0[1];
3. b := p0[2];
4. p0^ := r - ((r * Amount) shr 8);
5. p0[1] := g - ((g * Amount) shr 8);
6. p0[2] := b - ((b * Amount) shr 8);
7. inc(p0,3);  // next 3 bytes
8.

the_magik_mushroom

• Newbie
• Posts: 4
Re: fast code to lower an image brightness
« Reply #4 on: March 12, 2023, 08:09:37 pm »
thanks for all the answer