Quote Originally Posted by Avatar
I remember you can modify the palette in order to have a fade(just increase the colors values each refresh) ... But it was when I worked on 8 bits palette ... I don't know if 32 bits is that easy to modify ^^

Bye
Avatar
Nope, unfortunately it's not as simple as that in 32 bit colour . More's the pity!

Now, about the previous code: you probably want to remove the property access in the inner loop. A quick, unrelated example to show what I mean:

[pascal]var
i: Integer;
begin
for i := 0 to class1.property1.property2.property3 - 1 do
Whatever;
end;[/pascal]

changes into...

[pascal]var
i: Integer;
BlahCount: Integer;
begin
BlahCount := class1.property1.property2.property3;
for i := 0 to BlahCount - 1 do
Whatever;
end;[/pascal]

Next up: you don't want to be touching the .scanline in the inner loop either. The bitmap's memory itself will not change location, which means that you can calculate the offset from one row to the next. Here's a quote from Danny Thorpe from an article I'll ]

On the question of performance impact of calling Scanlines[] a lot: Yes, there is a potential performance hit. The DIBSection's memory buffer is not guaranteed to be coherent (reflect the most recent GDI operations) unless you call GDIFlush before accessing the pointer. The ScanLines[] property has to call GDIFlush to ensure the buffer contents are in sync. If the bitmap has been modified by GDI calls, then the call to GDIFlush could block waiting for the GDI pipeline to empty. If no modifications are still pending, GDIFlush should return immediately, but there will always be the overhead of making an additional call.

Additionally, TBitmap.GetScanlines() calls TBitmap.Changing, which may have to create a completely new, unshared copy of the image if the bitmap is shared. That will completely blow out performance on the first touch of Scanlines, and it chips away a little even when the bitmap isn't shared.

The technique shown in Listing 13 for minimizing time lost to ScanLines[] was developed by me while writing the TJPEGImage class. There is more at work here than meets the eye, though, which should be mentioned with that listing. The easiest way to eliminate calls to ScanLines[] is to simply do your own pointer arithmetic to advance the start-of-scanline buffer pointer to the next scanline. There are two hazards in doing that: 1) correctly dealing with the DWORD alignment of scan lines, and 2) the physical layout of scanlines in the memory buffer. DIBs can be oriented as "top-down", where the first row of pixels in the bitmap reside in the first bytes of memory in the buffer, or as "bottom-up", where the first row of pixels reside in the last bytes of memory and grow upward in memory. Oddly enough, "bottom-up" is the more common DIB orientation, possibly due to BMP's OS/2 origins.

The technique of subtracting the address of Scanline[0] from the address of Scanline[1] solves both problems very nicely. It gives you the distance between scanlines including DWORD padding, if any, and the sign of the delta implicitly indicates the DIB memory orientation. This eliminates the need for performance-robbing conditional statements in the critical pointer advancement loop. Just increment the pointer by that delta, and it will put you on the next scanline, be it above or below the current address.[/quote]
The article is at EFG's site: http://www.efg2.com/Lab/ImageProcessing/Scanline.htm

Also, note that EFG has an example about fading to/from black, which you can use to compare and constrast with the code above. The report: http://www.efg2.com/Lab/ImageProcessing/fade.htm

I'd offer to optimise the code myself but lately I've found myself breaking promises like that, unfortunately. However, the above should give some ideas.