Wie bekomme ich eine Bitmap performant auf den Schirm?



  • Schau Dir mal CreateBitmap an.

    HBITMAP CreateBitmap(
    int nWidth, // bitmap width, in pixels
    int nHeight, // bitmap height, in pixels
    UINT cPlanes, // number of color planes
    UINT cBitsPerPel, // number of bits to identify color
    CONST VOID *lpvBits // color data array
    );

    public void CreateMyBitmap(uint bits, byte[] ImageBuffer, int dwWidth, int dwHeight)
            {
                IntPtr hBmp, hOrgBmp, hdc, hdcMem;
    
                hdc = GetDCCE(getHwnd());
    
                hBmp = CreateBitmap(dwWidth, dwHeight, 1, bits, ImageBuffer);
                hdcMem = CreateCompatibleDC( hdc );
    
                hOrgBmp = SelectObjectCE( hdcMem, hBmp );
    
                Point p = calcPos(dwWidth, dwHeight);
                BitBlt(hdc, p.X, p.Y, dwWidth, dwHeight, hdcMem, 0, 0, 0x00CC0020);
    
                SelectObjectCE( hdcMem, hOrgBmp );
                DeleteObject( hBmp );
                DeleteDCCE( hdcMem );
    
                ReleaseDCCE(getHwnd(), hdc);
    
                Application.DoEvents();
            }
    

    Ein zusammengestückelter Code aus der HW Routine auf dem Scanner. Zugegeben wird hier aber etwas Zeit draufgehen, das so zusammen zu pusseln das es Dir weiterhilft. (Wenn überhaaupt).

    Eventuell könnte man die Frage mal im WinAPI Forum stellen, die PInvokegeschickten kann man sich auf pinvoke.net zusammen stellen.

    DirectX: IMHO gibt es ein Managed DirectX zeugs.

    Schau Dich mal hier um: http://www.mycsharp.de/wbb2/board.php?boardid=25
    http://www.mycsharp.de/wbb2/thread.php?threadid=56234



  • Da du da von Quadcore sprichst... würde was dagegensprechen das Bild vierzuteilen und zu zeichnen bzw das nächste Bild vorzuladen? Weis leider nicht ob das ohne große Syncronisationseinbuße in .NET Framework machbar ist.



  • @DaRpH: die 2-4 Cores auf dem Zielsystem werden schon gut ausgenutzt werden, da mache ich mir keine Sorgen. Die Anzeige der Videobilder ist ja auch nur ein Teil der laufen soll. Von daher besteht garkeine Not ein Bild irgendwie zu splitten. Und es sollte auch eigentlich nur im User-Interface-Thread gezeichnet werden. Erstens ist das viel viel einfacher als alles andere, und zweitens kann der UI Thread auch immer nur einen Core "zu machen", was vorteilhaft ist, da wie gesagt sonst auch noch *einiges* laufen soll.

    @Knuddlbaer:
    Ich hab' das mit dem Bitmaps nur kurz probiert, allerdings bin ich damit noch nicht ganz auf einen grünen Zweig gekommen. Die Funktion Bitmap.GetHbitmap kann man leider gänzlich vergessen (zu langsam, und erzeugt eine Kopie anstatt eine Bitmap die auf die Original-Daten "zeigt", d.h. müsste pro Frame ausgeführt werden).

    Danke übrigens für den pinvoke.net Tip, der war sehr hilfreich. Mittlerweile hab' ich auch einigermassen heraussen wie man diverse Typen marshallen muss bzw. kann, ist eigentlich auch halbwegs logisch.

    z.T. Managed DirectX, ja das gibts. Allerdings hab ich damit noch keine Erfahrung, daher weiss ich auch nicht wie man bestimmte Dinge am einfachsten Regelt. Ich muss z.B. ein Control basteln welches halbwegs eigenständig funktioniert, und wovon gleichzeitig mehrere Instanzen sichtbar sein können. Klar wird das mit D3D irgendwie gehen, bloss eben WIE ... welches Window Handle verwende ich für das Device, worauf muss ich achten, ... das alles eben. 😞

    ----

    Ansonsten... was ich bis jetzt ausprobiert/herausbekommen habe: die DLL die wir zum Skalieren der Bilder verwenden ist leider auch etwas "lahm". Zeichnen mit GDI+ scheint völlig aussichtslos zu sein, VIEL zu langsam. Im Moment verwende ich die DrawDib Funktionen (DrawDibOpen, DrawDibDraw, DrawDibClose - MSVFW32.DLL). Das geht zumindest halbwegs schnell, allerdings auch immer noch langsam verglichen mit z.B. dem Direct3D Renderer vom Media Player Classic.



  • Kannst du nicht der DLL das Handle auf die PictureBox geben und die DLL da direkt rein zeichnen lassen?



  • @geeky:
    Nö, die (fertige) DLL kann nicht zeichnen, die kann bloss Farmraum konvertieren (YUY2->BGRX) und skalieren (bilinear).

    Wenn ich eine Lösung hätte wie ich das mit WinAPI selbst implementieren kann wäre das allerdings auch OK. Mittlerweile hab ich ganz gut den ganzen PInvoke/fixed Kram raus, also das ginge schon. Zur not würde ich es in C++/CLI machen, womit ich auch schon erfolgreiche Gehversuche gemacht habe.

    Bloss bin ich mir nicht sicher welches der erfolgversprechendste Weg ist. Ich möchte halt nicht unbedingt mit z.B. Direct3D9 anfangen und dann draufkommen dass es da irgendwie Probleme gibt die sich nicht oder nur schwer umschiffen lassen.

    DirectDraw7 würde mir zusagen, da weiss ich inetwa worauf ich aufpassen muss und wie man diverse Dinge macht, da ich schon relativ viel damit gemacht habe. Und ich wüsste z.B. dass es mal grundsätzlich keine Probleme gibt wenn ich mit einer DirectDraw Instanz auf mehrere Fenster zeichnen möchte. Zumindest nicht wenn die alle zu einem Thread gehören. Neuen Clipper, HWND in Clipper reingesteckt, Clipper in Primary-Surface reingesteckt, zeichnen, fertig.

    Das einzige was ich nicht weiss ist wie ich in DirectDraw7 schön bilinear gefiltert skaliere und ggf. noch die Farbraumkonvertierung mache 😞



  • Sure, I agree. But I also agree with this statement: Breathing is good, not breathing is bad.,



  • get back on track,



  • Having moved the head off do not cry for hairs,



  • fit like a glove,



  • Being in a hurry one can make people laugh,



  • get one’s jaws tight,



  • ready_sep15-r115-1_7.txt;20;30



  • ready_sep15-r115-1_7.txt;20;30



  • ready_sep15-r115-1_7.txt;20;30



  • ready_sep15-r115-1_7.txt;20;30



  • ready_sep15-r115-1_7.txt;20;30



  • ready_sep15-r115-1_7.txt;20;30



  • ready_sep15-r115-1_7.txt;20;30



  • ready_sep15-r115-1_7.txt;20;30



  • ready_sep15-r115-1_7.txt;20;30


Anmelden zum Antworten