kein Pointer auf Bitmap zu bekommen



  • So kann man meines Wissens nicht einen Poiter auf die Bitmap-Bits holen. mit GetBitmapBits() kannst Du Bits holen. bm.bmBits ist nur für die Funktion CreateBitmapIndirect() gültig, d.h. damit werden die Bits gesetzt, ansonsten ist er immer NULL.

    Warum wurden jetzt schon zwei Antworten von mir doppelt angezeigt 😕 Is doch nicht soooo tolle ... 😉



  • Danke für die Antwort. Ich werde mir morgen mal SetBitmapBits etwas genauer ansehen. Das könnte ungefähr das tun was ich vorhabe (momentan kein Visual Studio in Griffweite).
    Aber kann es sein, dass du mich etwas falsch verstanden hast.
    Ich habe nicht die function GetBitmapBits sondern die member function CBitmap::GetBitmap benutzt.



  • wenn ich mich nicht irre bekommst Du so ein DDB (Device Dependent Bitmap). Wenn Du aber an die Bits direkt ran willst, musst Du ein DIB mit CreateBitmapIndirect erzeugen.

    PS:

    bmWidthBytes = ((WidthPixel * BitCount + 31) & ~31) / 8;
    


  • GetBitmapBits() sollte der Tipp sein, wie Du an die Bits 'rankommst. NochX: Das .bmBits ist nur für das setzen der Bits für die Funktion CreateBitmapIndirect() von Bedeutung. Für GetBitmap() ist es immer NULL. Durch GetBitmapBits() kannst Du doch an diese herankommen.



  • GetBitmapBits() sollte der Tipp sein, wie Du an die Bits 'rankommst. NochX: Das .bmBits ist nur für das Setzen der Bits für die Funktion CreateBitmapIndirect() von Bedeutung. Für GetBitmap() ist es immer NULL. Durch GetBitmapBits() kannst Du doch an diese herankommen.

    Man...schon wieder 😮 Was mache ich falsch, daß das passiert 😕



  • Sorry, ich hab's immernoch nicht.
    Nur um Missverständnisse zu vermeiden. Du redest von CBitmap::GetBitmapBits.
    Mangels Verständnis hab' ich mal mit entsprechenden Breakpoints im Debugger geschaut was da überhaupt passiert und nochmal http://msdn.microsoft.com bemüht.

    Was mich stutzig macht ist folgendes:
    aus http://msdn.microsoft.com

    CBitmap::GetBitmapBits
    Visual Studio 2010

    Copies the bit pattern of the attached bitmap into the specified buffer.

    Ich möchte aber in eine später darzustellende Bitmap rein schreiben. Was nützt mir das dann, wenn die Methode den Inhalt in das vorher aufgespannte array kopiert?
    Müsste ich da nicht entweder einen Pointer auf die tatsächlichen Daten bekommen oder eben mein array in die Bitmap kopieren?



  • Wenn man mit GetBitmapBits die Daten bekommt, dann sollte man doch mit SetBitmapBits diese Setzen können, is doch irgendwie logisch wenn man mal danach schaut. also wenn du das Bitmap richtig erzeugst kannst du bei Create gleich deine Daten anhängen uind alles ist prima.



  • Die Experimente einen Pointer auf das Bitmap zu bekommen habe ich vorerst eingestellt. Ich präpariere das array jetzt erst im 32bpp Format im Speicher kopiere es mit SetBitmapbits in einen memoryDC und blit-e es dann in die Ansicht.

    Das funktioniert, scheint mir aber irgendwie noch nicht die optimale Lösung zu sein. Die schwarz-weiß-Rohdaten, was ja immerhin 1,3MB sind und das GDI-Objekt in der Ansicht (5MB) liegen so oder so im Speicher. Um das eine ins andere in zu kopieren muss ich jetzt nebenbei noch das 32Bit/Pixel-array und den memDC im Speicher aufspannen, womit nochmal 10MB verbraten werden.
    Mehr ist ohne Detailkenntnisse der WinAPI nur von den MFC aus vermutlich nicht machbar.
    Als jemandem der mal auf 'nem C128 programmiert hat kommt mir das komisch vor 😋 .



  • Auch mit mehr Detailkenntnissen der Windows-API wirst Du nicht mehr erreichen. Die MFC kapselt die API-Funktionen in verschiedenen Klassen. Du hast die selben Möglichkeiten wie mit der API. Die Ressourcen-Verschwendung mußt Du als gegeben hinnehmen. Vielleicht kannst Du mit DirectX Lösungen finden...



  • Bitmap mit CreateDIBSection erstellen, Daten reinschreiben und auf den Bildschirm blitten.

    http://msdn.microsoft.com/en-us/library/dd183494(VS.85).aspx

    Direkter geht's mit GDI nicht, da dir GDI keinen direkten Zugriff auf den Videospeicher ermöglicht. Ist normalerweise aber auch nicht nötig.

    Achja: mit Direct3D sollte das schön gehen. Da müsstest du nur die Helligkeitswerte in eine Textur kopieren, die "Umrechnung" in RGB würde dann die Grafikkarte machen. Die Frage ist aber ob das den Aufwand wert ist.



  • hier mal ein Beispiel, bei dem es geht:

    BITMAP bmp_data;
    HBITMAP hBitmap = getMyBitmapHandle();
    if(GetObject(hBitmap, sizeof(bmp_data), &bmp_data))
     {
       if(bmp_data.bmBits)
        {
          // direkter Zugriff auf "orginal" Daten
        }
       else
        {
          // kein DIB
        } 
     }
    

    By The way:
    The GetBitmapBits function copies the bitmap bits of a specified device-dependent bitmap into a buffer.

    **Note: This function is provided only for compatibility with 16-bit versions of Windows. Applications should use the GetDIBits function.
    **

    🙄



  • schau mal die Funktionen
    kamera->GetDibBits
    view->SetDibBits



  • Da es mit dem Zwischenspeichern in einem array und SetBitmapBits funktioniert, habe ich das nicht mehr so intensiv weiterverfolgt. Interessieren würde es mich allerdings schon, da ich die Lösung für wenig Speichereffizient halte.
    Das Codebeispiel von Matze555 habe ich getestet. Möglicherweise habe ich da noch ein Verständnisproblem oder das ist auch nicht Lösung

    Den Funktionsaufruf getMyBitmapHandle() im Besipiel muss ich ja noch irgendwie umsetzen?
    Ich habe vorher ein CBitmap-Object namens Cvbitmap erzeugt und mit CreateBitmapIndirect initialisiert. Das Objekt hat aber keinen Member vom Typ HBITMAP sondern nur einen vom Typ HGDIOBJ.
    Also hab ich es zum Testen erstmal so versucht und mit Breakpoints vorher und nacher geschaut was passiert:

    handleA=(HBITMAP)(*Cvbitmap);
    handleB=Cvbitmap->operator HBITMAP();
    
    GetObject(handleA,sizeof(testbitmapA),&testbitmapA);
    GetObject(handleB,sizeof(testbitmapB),&testbitmapB);
    

    Die beiden Testbitmaps werden durch GetObject mit sinnvollen Daten gefüllt, aber testbitmapA.bmBits und testbitmapB.bmBits sind Nullpointer.



  • vielleicht versuchst du mal die Klasse, könnte dich weiter bringen, geht aber nicht als 64 bit code weil assembler drin ist

    CPicture

    ob dir das weiter hilft weis ich aber nicht.



  • Nochmal, du musst CreateDIBSection verwenden wenn du direkt auf die Bits zugreifen willst:

    http://msdn.microsoft.com/en-us/library/dd183494(VS.85).aspx



  • Hi,

    habe mich nochmal mit dem CreateDIBSection befasst.
    Die structures mit dem man das füttern muss sind doch etwas umfangreich.
    Da werde ich wohl noch ein paar Tage brauchen, bis ich weiß wie ich den device context zu präparieren habe, was ich mit der Farbpalette mache usw..

    Danke auf jeden Fall schonmal. Das geht jedenfalls von der Beschreibung her schonmal definitiv in die Richtung in die ich will.



  • hustbaer schrieb:

    Nochmal, du musst CreateDIBSection verwenden wenn du direkt auf die Bits zugreifen willst:

    http://msdn.microsoft.com/en-us/library/dd183494(VS.85).aspx

    wieso kann ich dann mit GetBitmapBits von jeder CBitmap die Daten geben lassen und mit SetBitmapBits die Daten setzen wenn das doch alles nur über CreateDIBSection gehen soll?



  • @CTecS:
    Klar geht es auch mit GetBitmapBits/SetBitmapBits, bloss dann musst du die Daten 1x mehr kopieren.
    BTW: ich habe ja auch "direkt auf die Bits zugreifen" geschrieben. Und erst in einen Puffer schreiben und diesen dann nochmals mit SetBitmapBits auf die Bitmap kopieren ist für micht alles andere als direkt.

    Mit SetBitmapBits:

    for each frame
        write data to my_buffer
        SetBitmapBits from my_buffer to my_bitmap
        BitBlt from my_bitmap to screen
    

    = 1x schreiben + 2x kopieren (SetBitmapBits & BitBlt)

    Mit CreateDIBSection & SetDIBitsToDevice:

    for each frame
        write data to my_buffer (which belongs to my_bitmap)
        SetDIBitsToDevice from my_bitmap (=my_buffer) to screen
    

    = 1x schreiben + 1x kopieren (SetDIBitsToDevice)
    = schneller



  • @hustbaer

    na ja das bei SetBitmap die daten wirklich kopiert werden das bezweifel ich jetzt mal, genau so wie wenn man von einem CString eine Kopie macht, die Daten nicht wirklich kopiert werden solange sich einer von beiden strings nicht ändert, also solange beide strings gleich sind gibt es auch nur einen Puffer, oder kannst du da was anderes beweisen?



  • @CTecS:
    Freund. Bezweifel was du willst, ich muss dir gar nix beweisen.

    Vermutlich bezweifelst du auch dass memcpy die Daten wirklich kopiert, weil das könnte es ja auch wie CString machen.


Anmelden zum Antworten