Also dass du nichts addieren musst liegt daran, dass jetzt nichts falsch gemacht wird
Wo genau der Fehler liegt, kann ich dir nicht sagen. Ich weiß nicht wie du InfoSize berechnet hast.
Dass was du jetzt machst basiert zu großen Teilen auf fast direkten Speicherzugriffen. In einer Bitmap (als Datei) stecken zwei Dinge, ein Bitmapheader (der enthält alle Metainfos wie Größe, Komprimierung, Farbtiefe,...) und der eigentlichen Bitmap (also wirklich die rohe Tabelle der kodierten Pixel).
Windows arbeitet auch direkt mit DIBs (dass ermöglicht, da Geräteunabhängig die ausgabe auf beliebigen Geräten). Wenn du dir die GetDiBits der WindowsApi anschaust, so steht dort
Zitat:
The GetDIBits function retrieves the bits of the specified bitmap and copies them into a buffer using the specified format.
int GetDIBits(
HDC hdc, //
handle of device context
HBITMAP hbmp, //
handle of bitmap
UINT uStartScan, // first scan line to set in destination bitmap
UINT cScanLines, // number of scan lines to copy
LPVOID lpvBits, // address of array for bitmap bits
LPBITMAPINFO lpbi, // address of structure with bitmap data
UINT uUsage //
RGB or palette index
);
Parameters
....
cScanLines
Specifies the number of scan lines to retrieve.
....
Wie du hier siehst macht Windows also gar nicht so viel mehr als auch nur ein paar ScanLines in einen Puffer zu kopieren. Windows speichert dabei aber eine Bitmap in den zwei unterschiedlichen Teilen ab (die Bits und die BitmapInfo Struktur). Delphi's Kapselung fast nur diese beiden Teile zusammen. Zudem sind Delphi Bitmaps Devicedependend.
Der Scanline Befehl (von der Delphi TBitmap) hingegen greift wieder direkt auf die Daten der zugrunde liegenden DIB zu. DIBs werden dabei von unten nach ob abgetastet (ScanLine[0] = unterste Zeile). Da du so also nichts anderes tust als der Windowsbefehl GetDiBits, sollte es also auch korrekt funktionieren. Du kannst natürlich auch die Windowsfunktion verwenden, nur müsstest du erst das BitmapInfo aus der TBitmap extrahieren um es dann wieder zu verwenden. Da Delphi seine eigene Struktur natürlich kennt, umgehst du so die Redundanz.
Was ich natürlich vergessen habe hinzuschreiben ist, dass du das dynamische Array wieder freigeben solltest, wenn du fertig mit der Benutzung bist. Jeder Aufruf von setLength alloziert sonst nur unnötig neuen Speicher ohne den alten frei zu geben (und das kann dir schnell deinen Speicher bis zum Prog.ende zu Müllen).
Einfach nach der Benutzung mit
Delphi-Quellcode:
finalize(bits);
setLength(bits, 0);
wieder frei geben.
Gruß Der Unwissende