Bilder möglichst effizient darstellen



  • Ich bearbeite grade ein Projekt in dem es um Bildverarbeitung geht.
    Ich bin für die Akquirierung der Bilder zuständig. Die Bilddaten werden von einer Kamera empfangen und in den Speicher geschrieben.

    Soweit so gut. Es soll aber ein Vorschaubild auf der GUI angezeigt werden, dabei müssen aber unbedingt noch genügend Ressourcen für eventeulle Bildverarbeitungsschritte übrig bleiben.

    Frage: Wie bekomme ich die Bilder mit möglichst geringer Prozessorlast dargestellt?
    ich glaube in der vorgängerversion wurde es über Bitmaps(bmiHeader setzen, winapi) gelöst, das ist aber recht Prozessorlastig. gibt es eine bessere Möglichkeit? vllt über directX oder ähnliches?

    Vielen Dank
    Gruß
    Martin



  • Vielleicht hilft hier GDI+ weiter?



  • Ich würde hier eher gucken ob nicht DirectShow für das ganze verwendet werden kann, also nicht für den Vorschau-Teil alleine, sondern fürs ganze Capturing + Vorschau.

    Vielleicht mal einfach ein paar DirectShow capture Samples angucken?



  • Effizient kannst Du Bilder *nur* mittels BitBlt darstellen. Alles andere ist zu langsam.
    Also, erzeuge eine Bitmap, was die *passende* Auflösung und Farbtiefe zu den aktuellen Einstellungen hat, dann kannst Du es mit BitBlt rasend schnell darstellen.

    PS: GDI+ nimmt Dir nur viel Arbeit ab, belastet aber den prozessor noch mehr! Also: Performance != GDI+!



  • Jochen Kalmbach schrieb:

    PS: GDI+ nimmt Dir nur viel Arbeit ab, belastet aber den prozessor noch mehr! Also: Performance != GDI+!

    Das ist interessant. Ich meine immer wieder gelesen/gehört zu haben, wenn man z.B. bei sehr komplexen Steuerelementen GDI+ verwendet kommt man "schneller" zum Ziel. Schnell im Sinne von Performanz.



  • Äh. Jochen. Wie stelle ich ein Bild mit BitBlt dar, wenn ich es irgendwo im Speicher rumliegen habe?

    Und wieso sollte BitBlt schneller sein als DirectShow?



  • Jochen Kalmbach schrieb:

    Effizient kannst Du Bilder *nur* mittels BitBlt darstellen. Alles andere ist zu langsam.
    Also, erzeuge eine Bitmap, was die *passende* Auflösung und Farbtiefe zu den aktuellen Einstellungen hat, dann kannst Du es mit BitBlt rasend schnell darstellen.

    So nachdem ich es lange genug rausgschoben habe, muss ich mich jetzt mit der ausgabe als vorschau beschäftigen.
    das mit BitBlt leuchtet mir ein. ich habe ein sample-programm gefunden, dass StretchDIBits benutzt, das sollte ja in dem Zusammenhang ungefähr das gleiche machen (bei dem DIB und DDB sehe ich noch nicht so ganz durch).
    Mein Problem ist grade nur das ich in der Fensterprogrammierung noch relativ neu bin und ich deshalb zwischen DCs und co. hin und herschleuder.

    int StretchDIBits(
      HDC hdc,                      // handle to DC
      int XDest,                    // x-coord of dest. upper-left
      int YDest,                    // y-coord of dest. upper-left
      int nDestWidth,               // width of dest. rectangle
      int nDestHeight,              // height of dest. rectangle
      int XSrc,                     // x-coord of src upper-left
      int YSrc,                     // y-coord of src upper-left
      int nSrcWidth,                // width of src rectangle
      int nSrcHeight,               // height of src rectangle
      CONST VOID *lpBits,           // bitmap bits
      CONST BITMAPINFO *lpBitsInfo, // bitmap data
      UINT iUsage,                  // usage options
      DWORD dwRop                   // raster operation code
    );
    

    Also: der erste Parameter muss sicher ein DC sein, wo ich das bild reinzeichnen will. FRAGE: wie lege ich am besten einen fensterbereich fest? zb bei einer dialog-basierten anwendung muss ich doch irgendwie wenn ich das hdc erstelle festlegen, wo das auf der form seien soll!?
    ein paar größenparameter ... sollte klar sein
    CONST VOID *lpBits ist dann sicher mein zeiger auf die bilddaten die ich ja schon im speicher habe.
    CONST BITMAPINFO *lpBitsInfo muss man irgendwie setzen, das sollte dann auch machbar sein.

    Wäre nett wenn mir jemand bei dem hDC-Problem weiterhelfen könnte und ansonsten mal sagt ob ich soweit richtig liege.

    Dankeschön!

    kurz zu directShow: das capturing und die anzeige wurde früher mit directShow gemacht genügt aber aus einigen unterschiedlichen Gründen nicht mehr den Anspüchen. u.A. konnte man die Kameraparameter nicht in geeigneter Weise einstellen.



  • hustbaer schrieb:

    Äh. Jochen. Wie stelle ich ein Bild mit BitBlt dar, wenn ich es irgendwo im Speicher rumliegen habe?

    Du musst es natürlich zuerst in das passende Format konvertienren 😉

    hustbaer schrieb:

    Und wieso sollte BitBlt schneller sein als DirectShow?

    Ich hatte BitBlt nicht mit DirectX verglichen... sondern mit GDI+...

    HaJo. schrieb:

    Das ist interessant. Ich meine immer wieder gelesen/gehört zu haben, wenn man z.B. bei sehr komplexen Steuerelementen GDI+ verwendet kommt man "schneller" zum Ziel.

    Ja, man kommt schneller zum Ziel!!! Aber eben aus Sicht des Programmierers und nicht aus Performance-Sicht 😉



  • hallo,
    ich weiß ich stelle recht grundlagenorientierte fragen, das tut mir ja auch leid.

    ich hab mich heute mal ein bisschen belesen und schonmal einen teilerfolg erzielt.

    ich hab

    HDC hDC=GetWindowDC(NULL);
     StretchDIBits(hDC,
                        0,
                        0,
                        400,
                        400,
                        0,
                        0,
                        400,
                        400,
                        pImage,pBitmapInfo,DIB_RGB_COLORS,SRCCOPY);
    

    dabei hab ich pImage mit Bilddaten gefüllt und pBitmapInfo mit den entsprechenden Infos über breite, höhe, farben, ...
    wie beschrieben hab ich das mit dem HDC noch nicht so ganz hinbekommen. der obere code produziert ein bild das 400*400 pixel in der ecke des bildschirms klebt. GetWindowDC(NULL) liefert also den gesamten biildschirm als handle.
    Wie kann ich einen bestimmten bereich für den DC angeben? das muss doch recht einfach irgendwie gehen 😕

    Dankesehr
    Martin



  • hab jetzt selber noch was rausgefunden, der bereich des dialogfensters selber ist nicht mit GetWindowDC(NULL); sondern mit GetDC(m_hWnd); zu handlen.
    🙂

    ich danke trotzdem.


Anmelden zum Antworten