Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Multimedia (https://www.delphipraxis.net/16-multimedia/)
-   -   Delphi Bitmap als Pointer auf einem Display ausgeben (https://www.delphipraxis.net/66529-bitmap-als-pointer-auf-einem-display-ausgeben.html)

Cyberaxx 30. Mär 2006 23:31


Bitmap als Pointer auf einem Display ausgeben
 
Hallo,

bin gerade dabei an einer Ansteuerung eines Displays zu arbeiten und benötige eventuell noch ein wenig Hilfe bei der richtigen Umsetzung.

Die Dll zur Ansteuerung des Displays besitzt eine Funktion mit der man ein "Bitmap" direkt übertragen kann. Das Bitmap muss vom Typ Pointer.

Delphi-Quellcode:
Function LUI_Bitmap(DevNum: Integer; ScreenNr: Byte; ScreenPosX: Integer; ScreenPosY: Integer;
  BMPoffsetX: Integer; BMPoffsetY: Integer; BMPWidth: Integer; BMPHigh: Integer;
  BMPdataWidth: Integer; BMPdataHigh: Integer; Bitmap: Pointer): Byte; StdCall; External 'LUIse.dll'
Habe dann überall gesucht und bin dann auf etwas gestossen, was mit das Bitmap in einen Pointer setzt.

Delphi-Quellcode:
procedure TDisplay.BMPtoPointer(Bitmap: TBitmap);
  var
    Info : PBitmapInfo;
    InfoSize : DWord;
    Image : Pointer;
    ImageSize : DWord;
  begin
    with Bitmap do
    begin
      GetDIBSizes(Handle, InfoSize, ImageSize);
      Info := AllocMem(InfoSize);
      try
        Image := AllocMem(ImageSize);
        try
          GetDIB(Handle, Palette, Info^, Image^);
          { Bild an das Display übergeben }
          _Bitmap(0, 0, 30, 120, 0, 0, Width, Height, 320, 240, Image); // umsetung von LUI_Bitmap
        finally
          FreeMem(Image, ImageSize);
        end;
      finally
        FreeMem(Info, InfoSize);
      end;
    end;
  end;
Die Funktion leistet auch wunderbare Dienste. Einzieger Nachteil ist es ist Vertikal gespiegelt. Das ist natürlich nicht gewollt!

Habe es dann vor der Ausgabe auf das Display vertikal gespeigelt.

Delphi-Quellcode:
PROCEDURE TDisplay.Spiegeln(VAR Bitmap: TBitmap);
BEGIN
    Bitmap.Canvas.CopyRect(Rect(0,Bitmap.Height-1, Bitmap.Width,-1),
                           Bitmap.Canvas,
                           Rect(0,0, Bitmap.Width,Bitmap.Height));
END;
Damit habe ich nun auf dem Display mein Bild so wie es sein soll.

Delphi-Quellcode:
Spiegeln(VisBuff);
BMPtoPointer(VisBuff);
Diese Funktion wird z.Z. alle 50ms aufgerufen, da sie das Audiospectrum wieder gibt.

Frage ist nun ob man das so lassen kann oder ob es dafür vllt. noch eine bessere und schnellere Methode gibt. Es ist für mich das erste mal das ich mit sowas arbeite also entschuldigt falls das nicht so die korrekte Umsetzung ist aber sie funktioniert z.Z.
Dies ist ja auch er Grund warum ich den Thread jetzt schreibe.

Gruss

Cyberaxx

himitsu 31. Mär 2006 10:06

Re: Bitmap als Pointer auf einem Display ausgeben
 
Ich bin mir gerade nicht ganz sicher, aber ist das interne Format in 'nem TBitMap nicht eh schon DIB?
Also wenn das so ist, könnte man sich ja eventuell den Pointer darauf besorgen und somit ein bissl Zeit sparren ... im Moment wird ja ein neues Bild (in Variable Image) erstlle und freigegeben.

Mir war auch schon der gedanke gekommen, daß man auf die INFO verzichten könnte, aber ich glaub mal nicht, daß es hier geht -.-''
Also etwa so?
Delphi-Quellcode:
procedure TDisplay.BMPtoPointer(Bitmap: TBitmap);
  var
    Image : Pointer;
    ImageSize : DWord;
  begin
    with Bitmap do
    begin
      GetDIBSizes(Handle, InfoSize, ImageSize);
      Image := AllocMem(ImageSize);
      try
        GetDIB(Handle, Palette, nil, Image^);
        { Bild an das Display übergeben } 
        _Bitmap(0, 0, 30, 120, 0, 0, Width, Height, 320, 240, Image); // umsetung von LUI_Bitmap
      finally
        FreeMem(Image, ImageSize);
      end;
    end;
  end;
PS: falls du Lust hast ... es geht auch kürzer (mußt nicht jedesmal INTEGER einzeln angeben) ^_^
Delphi-Quellcode:
Function LUI_Bitmap(DevNum: Integer; ScreenNr: Byte; ScreenPosX, ScreenPosY,
  BMPoffsetX, BMPoffsetY, BMPWidth, BMPHigh, BMPdataWidth, BMPdataHigh: Integer;
  Bitmap: Pointer): Byte; StdCall; External 'LUIse.dll';

Cyberaxx 31. Mär 2006 10:21

Re: Bitmap als Pointer auf einem Display ausgeben
 
Guten Morgen,

das will leider nicht so... :D

Delphi-Quellcode:
  var
    Image : Pointer;
    ImageSize : DWord;
  begin
    with Bitmap do
    begin
      GetDIBSizes(Handle, InfoSize, ImageSize);
Da fehlt das InoSize, habs hinzugefügt aber er braucht doch die Info :(

Delphi-Quellcode:
GetDIB(Handle, Palette, nil, Image^);

[Fehler] LUI.pas(173): Konstantenobjekt kann nicht als Var-Parameter weitergegeben werden

himitsu 31. Mär 2006 10:24

Re: Bitmap als Pointer auf einem Display ausgeben
 
Habsch mir fast schon gedacht ... bei vielen WinAPI-Funktionen funktioniert sowas ja, aber in Delphi halt nicht unbedingt -.-''

Ansonsten bleibt halt noch mein erster Vorschlag ... wenn intern wirklich DIB, dann direkt daruf zugreifen, ansonsten scheint's ja keinen anderen Weg zu geben.

Cyberaxx 31. Mär 2006 10:28

Re: Bitmap als Pointer auf einem Display ausgeben
 
Wenn Du mir kurz helfen würdest damit ich weiss wie ich drauf zugreifen sollte.

Ist ja das erste mal das ich damit arbeite... :(

himitsu 31. Mär 2006 12:18

Re: Bitmap als Pointer auf einem Display ausgeben
 
Leider habe ich so tief im TBitMap auch noch nicht rumgestöbert, mir ist nur so, als wenn ich mal was gelesen hatte, das TBitMap intern oftmals auch mit DIB's arbeitet (bzw. daß man ihm sagen kann, womit es arbeiten soll), demnach sollte es ja eine Möglichkeit geben auch direkt darauf zuzugreifen.
(hab im Moment auch nur mein D4 hier und kann demanch nicht ma schnell in den Quellcodes nachsehn, was z.B. die Funktion GetDIB intern macht)

Der_Unwissende 31. Mär 2006 18:08

Re: Bitmap als Pointer auf einem Display ausgeben
 
Hi,
ja, den richtigen Datentyp zu finden ist etwas komplizierter, du brauchst nämlich eine Variable vom Typ BitmapInfo (gehört zu GDI und damit zur Unit Windows).

Eine Bitmap unter Windows ist eigentlich nur eine Matrix von Pixeldaten. Alles zusätzliche speichert Windows getrennt in einem zur Bitmap gehörenden BitmapInfo (Breite, Höhe, Pixelformat, ...). Delphi kapselt einfach nur beides in dem so genannten TBitmap Objekt.

Damit deine Funktion funktioniert, musst du eine Variable vom Typ BitmapInfo anlegen (ok, hatten wir schon), genau so wichtig ist es aber, dass du deinen Zeiger Image nicht unitialisiert übergibst. Der muss auf ein Feld zeigen, dass groß genug ist um alle Pixelinfos der Bitmap aufzunehmen (also Width * Height * PixelFormat in Byte).

Gruß Der Unwissende

Cyberaxx 31. Mär 2006 18:17

Re: Bitmap als Pointer auf einem Display ausgeben
 
Soeben beim ändern der Bitmapgrösse wird das bitmap nicht mehr richtig dargestellt. ändere ich manuell den Wert des BMPdataWidth wird das Bild wieder richtig dargestellt. Je nach Grösse des Bitmaps ändert sich auch der Wert der zu BMPdatawidth addiert werden muss.

Hab mal grob rumgespielt. Wenn das Bitmap ne Breite von 200 hat liegt der Wert ca. bei 224.
Ist das Bitmap 100 Breit liegt der Wert bei ca. 130.

Hier mal der Auszug aus der Dokumentation:

Code:
LUI_Bitmap
Beschreibung:
Lädt die übergebenen Bild-Daten in den entsprechenden Grafik-Screen.
Syntax:
ErrorCode LUI_Bitmap (int DevNum, unsigned char ScreenNr, int ScreenPosX,
int ScreenPosY, int BMPoffsetX, int BMPoffsetY,
int BMPWidth, int BMPHight, int BMPdataWidth,
int BMPdataHight, unsigned char *Bitmap)
Code:
Parameter:
DevNum: Index des Gerätes (0…3)

ScreenNr: Grafik-Screennummer (0,1)

ScreenPosX: X-Koordinate der linken oberen Ecke des auszugebenden Bitmaps auf dem LCD

ScreenPosY: Y-Koordinate der linken oberen Ecke des auszugebenden Bitmaps auf dem LCD

BMPoffsetX: X-Offset der linken oberen Ecke des auszugebenden Bitmaps innerhalb der Bitmap-Daten (z.B. um nur einen Teilbereich eines Bitmaps auf dem LCD auszugeben)

BMPoffsetY: Y-Offset der linken oberen Ecke des auszugebenden Bitmaps innerhalb der Bitmap-Daten (z.B. um nur einen Teilbereich eines Bitmaps auf dem LCD auszugeben)

BMPWidth: Breite des auszugebenden Bitmaps

BMPHight: Höhe des auszugebenden Bitmaps

BMPdataWidth: Breite der gesamten Bitmap-Daten in Pixel

BMPdataHight: Höhe der gesamten Bitmap-Daten in Pixel

Bitmap: Zeiger auf Array mit Bitmap-Daten


Beispiel:
unsigned char ErrorCode;
int DevNum=0;
unsigned char BMPData[9600];
//BMPData[9600] mit Bitmapdaten laden (schwarz/weiß), z.B. Hintergrundbild 320x240
//…
ErrorCode = LUI_Bitmap (DevNum, 0, 0, 0, 0, 0, 320, 240, 320, 240, BMPData);
if (ErrorCode)
{
//Fehlercode auswerten, Fehlerbehandlung
}
else
{
//Bitmap (in diesem Beispiel full screen 320x240=9600Byte) wurde an Position x=0 und y=0, mit
einer Breite von 320 Pixel und eine Höhe von 240 Pixel in Grafik-Screen Nummer Null geladen.
Da das ganze Bitmap geladen werden sollte, sind BMPoffsetX und BMPoffsetY gleich Null.
}
//BMPData[9600] mit Bitmapdaten laden (schwarz/weiß), z.B. ein 320x240 Pixel Bitmap mit kleineren
//Grafiken für Animationen
//…
ErrorCode = LUI_Bitmap (DevNum, 1, 50, 30, 10, 15, 25, 25, 320, 240, BMPData);
if (ErrorCode)
{
//Fehlercode auswerten, Fehlerbehandlung
}
else
{
// Ein kleines Bitmap wurde an Position x=50 und y=40, mit einer Breite von 25 Pixel und eine
Höhe von 25 Pixel in Grafik-Screen Nummer 1 geladen. Das kleine Bitmap hat innerhalb des
gesamten Bitmaps die Position x=10 und y=15 (BMPoffsetX=10 und BMPoffsetY=15). Das kleine
25x25 Pixel Bitmap wurde quasi aus dem großen 320x240 Pixel Bitmap (BMPData -Array) an der
Position x=10, y=15 “ausgeschnitten” und auf dem LCD an der Position x=50, y=30 eingefügt.
}
Könnte mir jemand helfen, was es mit dem Wert auf sich hat?


Zitat:

Zitat von Der_Unwissende
genau so wichtig ist es aber, dass du deinen Zeiger Image nicht unitialisiert übergibst. Der muss auf ein Feld zeigen, dass groß genug ist um alle Pixelinfos der Bitmap aufzunehmen (also Width * Height * PixelFormat in Byte).

Könntest Du mir das bitte etwas genauer erklähren. Habe keine Ahnung von Pointern, da ich sie bisher nie nutzte.

Gruss

Cyberaxx

Der_Unwissende 1. Apr 2006 10:27

Re: Bitmap als Pointer auf einem Display ausgeben
 
Zitat:

Zitat von Cyberaxx
Zitat:

Zitat von Der_Unwissende
genau so wichtig ist es aber, dass du deinen Zeiger Image nicht unitialisiert übergibst. Der muss auf ein Feld zeigen, dass groß genug ist um alle Pixelinfos der Bitmap aufzunehmen (also Width * Height * PixelFormat in Byte).

Könntest Du mir das bitte etwas genauer erklähren. Habe keine Ahnung von Pointern, da ich sie bisher nie nutzte.

Aber gerne doch.
Also ein Pointer ist an sich nur ein Zeiger (ok, der Name verrät es doch irgendwie schon). Das klingt trivial, hat aber natürlich ein paar Konsequenzen. Der Pointer der auf 0xA02837B (<- irgendeine Adresse) zeigt, mag zwar gültig sein, aber was steht denn dort an der Adresse?
Ein Pointer ist wirklich nur ein Zeiger (man spricht auch von untypisiert), der zwar auf einen Adressbereich zeigt, dir aber durch nichts verrät, was dort steht.
GetDIBs erwartet jetzt als letzte zwei Argumente einfach nur Pointer, die auf eine BitmapInfo-Struktur zeigen bzw. auf einen Speicherbereich, der die Bits der Bitmap aufnehmen kann. Wenn du nur eine Lokale Variable p : Pointer anlegst, ist diese nicht initialisiert.
Im besten Fall zeigt dieser Zeiger auf 0x0 (= nil), dann bekommst du eine Accessviolation (der Speicherbereich 0 kann nie adressiert werden) und du findest deinen Fehler schnell. Weniger guter Fall wäre es, wenn der einfach mal auf einen ganz anderen Teil deines Programms zeigt. Dann wird die Methode die Bits einfach dort hin schreiben. Dass es nicht unbedingt von Vorteil ist sollte klar sein, aber was genau passiert ist nicht vorhersehbar.
Für die Bits gibt es mehrere Möglichkeiten gespeichert zu werden. Du könntest dir z.B. ein TByteDynArray anlegen, dass halt alle Bytes der Bitmap aufnehmen kann oder du benutzt GetMem oder oder oder.
Mit GetMem bekommst du auch einfach nur einen Zeiger zurück, damit wird wirklich ein roher Datenbereich (ohne Interpretation) alloziert. Was du mit dem machst ist dann deine Sache. Wichtig ist, der sollte tunlichst auch wieder freigegeben werden. Schau einfach in die Hilfe, da steht dann immer alles Wichtige (wie man Speicher alloziert und freigibt).
Ach ja, für den anderen Weg mit dem Array musst du die Adresse der ersten Zelle übergeben (@DeinArray[0]), dass wäre dann der gültige Zeiger.

Gruß Der Unwissende

[Edit] Edit hat sich erledigt[/Edit]

Cyberaxx 1. Apr 2006 17:21

Re: Bitmap als Pointer auf einem Display ausgeben
 
Hey

Ok soweit habe ich das nun verstanden. Oben hatte ich ja beschrieben das "Bitmap: Zeiger auf Array mit Bitmap-Daten" Aber wie setzte ich das dann nun um?

Delphi-Quellcode:
  var
    Image : Pointer;
Delphi-Quellcode:
GetDIB(Handle, Palette, Info^, Image^);
Image müsste demnach ein Byte Array sein, sehe ich das richtig?

Zitat:

Der muss auf ein Feld zeigen, dass groß genug ist um alle Pixelinfos der Bitmap aufzunehmen (also Width * Height * PixelFormat in Byte).
PixelFormat könnte ich demnach weg fallen lassen, da ich nur 1Bit farbtiefe auf dem Display ausgeben kann. Sah man bei meinem Beispiel nicht aber in konvertiere das Bitmap vorher zu 1Bit runter.

Das Byte Array kann ich das egal welche grösse es hat auf 320x240 Pixel festlegen? oder muss ich das an der aktuellen Grösse des Bildes anpassen?

Wie müsste ich das denn umsetzten, oder muss ich die Procedure umschreiben?

Es kommt aber noch ein Problem, was ich auch geschrieben habe BMPdataWidth scheint auch nicht zu stimmen aber aus der Doku werd ich da auch nicht ganz schlau.


[E] Hab jetzt ne Weile gesucht, bin auch fündig geworden über Arrays aber nun kommt ja das entscheidene wie setz ich denn meine Bilddaten ins Array? [/E]

Der_Unwissende 1. Apr 2006 20:18

Re: Bitmap als Pointer auf einem Display ausgeben
 
Also, Windows bietet auch die GetDiBits-Funktion und hier wird darauf verwiesen, dass nur ein mehrfaches Scanline durchgeführt wird. Das gleiche kannst du natürlich auch mit einem TBitmap machen.
Dazu legst du einfach ein Array an, dass die Bilddaten aufnehmen kann ((Breite * Höhe) / 8) wobei du darauf achten musst, dass deine Breite und Höhe auch vielfache von 8 sind (wegen der Organisation in Bytes).
Nun kannst du über die Höhe der Bitmap iterieren, eine Zeile mittels Scanline in den Speicher laden und in dein Array kopieren, fertig.

Delphi-Quellcode:
var row : Integer;
    bits : TByteDynArray;
    buffer : PByteArray;
begin
  // wegen 1 Bit / pixel
  setLength(bits, (Bitmap.Height * Bitmap.Width) div 8);
  for row := 0 to Bitmap.Height - 1 do
    begin
      buffer := Bitmap.Scanline[row];
      CopyMemory(@bits[row * (Bitmap.Width div 8), buffer, (Bitmap.Width div 8)];
    end; //  for row := 0 to Bitmap.Height - 1
end;
Das sollte es schon sein.

Cyberaxx 1. Apr 2006 20:44

Re: Bitmap als Pointer auf einem Display ausgeben
 
Delphi-Quellcode:
bits : TByteDynArray;
Ist undefiniert...

Delphi-Quellcode:
type Name = array of {array of ...} Base type; // Dynamic array
Muss ich mir das darunter vorstellen?

Wie gesagt habe weder bisher mit Pointern noch mit Arrays gearbeitet, ehrlich gesagt habe ich sie bisher auch nie gebraucht.

Habe auch einen Auszug gefunden der wohl das gleiche macht, aber da taucht genau sowas wieder auf.

Delphi-Quellcode:
procedure LCD_SendToGfxMemory(Pixels : TArrayType; X1,Y1,X2,Y2 : Word; inverted : boolean);
Als ich dort nachfragte kam nur "Das brauch Dich nicht zu interessieren, das kommt aus dem Programm!"

Vllt. stell ich mich in den Fall aber auch nur zu blöd an... War ja schon verdamt froh das es mit der Procedure im ersten Post funktionierte.

[E]
Delphi-Quellcode:
CopyMemory(@bits[row * (Width div 8), buffer, (Width div 8)];
Er meckert bei "buffer"

[Fehler] LUI.pas(193): Array-Typ erforderlich
[Fehler] LUI.pas(193): Nicht genügend wirkliche Parameter[/E]

Der_Unwissende 1. Apr 2006 22:04

Re: Bitmap als Pointer auf einem Display ausgeben
 
Sorry, ist natürlich ein dummer Fehler, die eckigen Klammern stimmen so natürlich nicht, korrekt ist :
Delphi-Quellcode:
  CopyMemory(@bits[row * (Width div 8)], buffer, (Width div 8));
Was TByteDynArray angeht, es ist einfach nur ein dynamisches Array vom Typ Byte und in der Unit Types deklariert (die musst du nur einbinden).

An sich sind Arrays sehr einfach (und praktisch). Wenn du sehr viele Variablen vom gleichen Typ hast, dann kannst du die sehr einfach in ein Feld (ein so genantes Array) schreiben. Dynamische Arrays sind dabei nicht auf eine Größe festgelegt (so wie statische).
An sich gibt es sehr viele Bereiche, in denen man dann mit Arrays arbeitet. Insbesondere in diesem Fall, die Bits einer Bitmap (oder Maps an sich) zahlen sich Arrays aus. Möchtest du etwa auf eine Zeile zugreifen, so liefert dir Scanline einen Zeiger auf ein Array, dass die Werte enthält.
Dabei kannst du dir ein Array als einen Speicherabschnitt vorstellen, der groß genug ist x-mal einen Datentyp zu speichern. Hättest du ein Array[0..9] of Integer, so hieße es, dass du 10 Felder vom Typ Integer (10 * 4 Byte) reservierst. Über einen Index kannst du dann auf einen einzelnen Wert zugreifen (deinArray[3] := ...). Ein Zeiger auf die erste Zelle reicht dabei aus. Möchtest du wie hier auf die 4te zugreifen, so weißt du dass diese (bei angenommener linearer Anordnung im Speicher) bei Adresse von deinArray[0] + (3 * 4 Byte) liegen muss. Das schöne ist, dass du nur den Index hinschreibst, Delphi kümmert sich schon drum.

Hättest du kein Array, hättest du halt das Problem, dass du für jedes Pixel der Bitmap eine eigene Variable bräuchtest. Das würde natürlich einen riesigen Overhead bedeuten (zu jedem Pixel hättest du eine 4 Byte Adresse und damit mehr Speicher verbraucht als die zugehörige Information). Zudem ermöglichen dir Arrays einen eher anonymen Zugriff, du gibst natürlich nur dem gesamten Feld einen Namen und greifst dann auf eine Bestimmte Zelle des Feldes zu (statt zig Variablen zu unterscheiden).

Cyberaxx 1. Apr 2006 22:22

Re: Bitmap als Pointer auf einem Display ausgeben
 
Hey danke nun funktioniert es und ich muss bei BMPdataWidth auch nix mehr zu addieren :)

Jetzt noch eine kleine Frage...

Code:
ErrorCode LUI_Bitmap (int DevNum, unsigned char ScreenNr, int ScreenPosX,
int ScreenPosY, int BMPoffsetX, int BMPoffsetY,
int BMPWidth, int BMPHight, int BMPdataWidth,
int BMPdataHight, unsigned char *Bitmap)
Bei meiner Ausgangsfunktion habe ich zu dem Wert BMPdataWidth was zu addieren müssen bei der jetzigen muss ich dies nun nicht mehr... Woran liegt das nun? Genau wie das das Bild nun nicht mehr auf dem Kopf steht...

Der_Unwissende 2. Apr 2006 11:28

Re: Bitmap als Pointer auf einem Display ausgeben
 
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


Alle Zeitangaben in WEZ +1. Es ist jetzt 13:11 Uhr.

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz