Eigenen Speicherbereich über HBitmap nach Graphics::TBitmap
-
Hallo,
bereits meine letzte Frage zielte ja auf den Versuch ab ein HBITMAP in das VCL-Gängige Graphics::TBitmap zu bekommen. Dabei soll das HBITMAP nur als umweg dienen, mein eigentliches anliegen ist es meinen eigenen Speicherbereich (in meinem Fall ein Array) als Bitmap darzustellen.
Hier mal mein Testcode:
BYTE aData[100]; for ( int x =0; x<100; x++ ) aData[x] = x; BITMAP bitmap; bitmap.bmType = 0; bitmap.bmWidth = 10; bitmap.bmHeight = 10; bitmap.bmWidthBytes = 10; bitmap.bmPlanes = 1; bitmap.bmBitsPixel = 8; bitmap.bmBits = aData; Graphics::TBitmap *bmp = new Graphics::TBitmap( ); bmp->Handle = CreateBitmapIndirect( &bitmap ); for( int y=0; y<bmp->Height; ++y ) { BYTE *ptr =(BYTE*) bmp->ScanLine[y]; for ( int x=0; x<bmp->Width; ++x ) ShowMessage(AnsiString(ptr[x])); } delete bmp;
Nun steigt er hier immer bei BYTE *ptr =(BYTE*) bmp->ScanLine[y]; mit einer Exception EOutofResources aus. Vielleicht hat jemand von euch ne Ahnung warum? Ich denke, das das Array wohl irgendwelche Probleme macht, vielleicht muss es ja auch anderes angelegt sein?
P.S. Falls ihr noch eine einfachere Methode wisst bzw. einen guten Link dazu (mein gegoogle war frustrierend) dann nehm ich natürlich auch das.
-
Warum so umstaendlich mit CreateBitmapIndirect???
Setz doch eines von bmp Width und Height auf die richtige Groesse!
PS: Das Pixelformat kann auch eingestellt werden!
-
udn wie bekome ich es dann hin, das das bitmap mein bereits vorhandes Array als Datenquelle für die Pixel verwendet?
-
Mit Bitmap->Canvas->ScanLines kannste auf die bildzeilen zugreifen.
Da wuerde ich fuer alle Bytes einer Zeile die Werte in 'ner Schleife zuweisen!
Das Pixelformat von Bitmap sollte aber auf 8Bit eingestellt werden. Dein Array ist doch so organisiert?
-
Graphics::TBitmap *bmp = new Graphics::TBitmap(); bmp->Width = 10; bmp->Height = 10; bmp->PixelFormat = pf8bit; bmp->Canvas->Rectangle(0, 0, 9, 9); for( int y=0; y<bmp->Height; ++y ) { BYTE *ptr =(BYTE*) bmp->ScanLine[y]; for ( int x=0; x<bmp->Width; ++x ) ShowMessage(AnsiString(ptr[x])); } delete bmp;
-
Du hast mich leider nicht richtig verstanden. Wenn ich es so mache wie du schreibst, kann ich ja nur Werte zuweisen. Dann habe ich aber Zwangsweise doppelt soviel Daten im Speicher nämlich das Array und das Bitmap.
Ich möchte aber das das Array als Quelle fürs Bitmap dient, also quasie für Scanline.Bsp.
Ich hab ein Bild (Größe 50 MB) welches ich beim laden in ein reines grauwerbild umwandel und nur die reinen Daten auslese und in ein Array schreibe. Das mache ich, weil die Art wie ich die Daten verarbeiten möchte, lässt sich leichter organisieren über das Array als wie über Scanline (meine Meinung). Wenn ich aber dann das Bild anzeigen möchte, habe ich natürlich keins, also muss ich mein datenarray wieder irgendie zu einem Bitmap Ojekt machen, welches aber als Bilddaten gleichzeitig mit auf das Array zugreift.
Sonst hätte ich statt 50 MB gleich mal 100 MB belegt und das soll vermieden werden, weil es später vorkommen kann das mehrere solcher Bilder im Speicher liegen.was willst du mir damit sagen?
-
Geo hat meine Aussage in c++ formuliert!
Das mit dem Speicher ist natuerlich ein Problem
- hast Du kein Geld fuer genug RAM?
Dan mach doch den hier:
- Leg ein Feld von Zeigern an auf je EINE Scanline.
- Groese dynamisch passend zu Bildhoehe.
- Lies alle ScanLines aus und speicher die adressen im Feld.- mit dem feld kannste auf alle Zeilen zugreifen, in Zeile auf alle Bytes.
-
Das hatte ich auch schon so, bis ich halt auf die Idee kamm, das ganze gleich in ein Array zu cachen.
Naja, falls ichs nicht hinbekomme so mit dem Array werd ich wohl auch wieder darauf zurückfallen müssen.Ist halt nur so, das das Laden und Bearbeiten des Bildes zeitkritisch sein können, wohingegen das Anzeigen des Bildes ruhig dauern kann. Da das nur fürs Parameter einrichten gebraucht wird.
Aber bevor ich mich jetzt noch sinnlos abmüh, werd ich das erstmal austesten ob und um wieviel das mit Array schneller ist.