[gelöst (sozusagen)] Verzerrte Schrift bei VMR9 Bitmap-Overlay



  • Hallo zusammen!

    Ich hab ein etwas kniffliges Problem:

    Ich hab mir eine Art Mediaplayer gebaut, welcher einen DirectShow Filtergraphen aufbaut, damit ein Video abspielt, und dieses Video mit einem Overlay (Text, Bild, etc.) überlagert.

    In den DirectX Samples hab ich das "Ticker" Beispiel gefunden, in dem der Video Mixing Renderer 9 benutzt wurde um das Overlay zu basteln.

    Das Ticker-Beispiel hab ich in meiner Anwendung schon nachgebaut. Funktioniert prima. Doch zum einen will ich keinen Lauftext, und zum anderen will ich mehrere Texte an verschiedenen Stellen über dem Video anzeigen. Den Lauftext abstellen ist kein Problem. Was mir Probleme macht ist das viel größere Bitmap das ich verwenden muss:

    Nehmen wir ein Beispiel: Ich hab ein Video mit einer Auflösung von 704x576 Pixeln. Dieses Video wird in originalgröße angezeigt. Wenn ich jetzt einen Text oben links und einen text unten rechts haben will, muss ich das Bitmap das ich darüber legen will also 704x576 PIxel groß machen. Das ist noch nicht das Problem. Der Text wird auch fehlerfrei angezeigt. Das sieht dann Beispielsweise so aus:

    http://img403.imageshack.us/my.php?image=normalsizezm8.jpg
    Damit ich sehe wie groß mein Overlay-Bitmap wirklich ist, hab ich 50% Alpha-Transparenz eingeschaltet und einen grünen Hintergrund verwendet. Wie man unschwer erkennen kann ist "Hallo Welt" der OverlayText in gelber Farbe auf rotem Hintergrund.

    Strecke ich das Videofenster in der Höhe, streckt sich das Video, der Text soll aber unverändert bleiben. Das funktioniert auch und sieht wie folgt aus:

    http://img410.imageshack.us/my.php?image=heightstrechedmj5.jpg

    Wenn ich das Video aber jetzt in der Breite strecke, so passiert irgendwas mit dem Text. Ich hab keine Ahnung wie das passiert, aber aussehen tut's so:

    http://img398.imageshack.us/my.php?image=widthstrechedvx9.jpg

    Je breiter ich das Video ziehe, desto weniger kann man vom Text erkennen.

    Kann sich das jmd. erklären?

    Programmtechnisch bin ich so vorgegangen:

    // schauen wie groß das Videofenster ist
    RECT videoWindowRect;
    GetClientRect(&videoWindowRect);
    
    // Ein Bitmap erzeugen das exakt so groß wie das Videofenster ist
    HBITMAP hBitmap = ::CreateCompatibleBitmap(hdc, videoWindowRect.right, videoWindowRect.bottom);
    BITMAP bitmap;
    HBITMAP hBitmapOld;
    GetObject(hBitmap, sizeof(bitmap), &bitmap);
    hBitmapOld = (HBITMAP)SelectObject(hdcBitmap, hBitmap);
    
    // Hintergrund testweise komplett grün machen
    HBRUSH hNewBrush = ::CreateSolidBrush( RGB(0,255,0) );
    FillRect(hdcBitmap,&videoWindowRect,hNewBrush);
    DeleteObject(hNewBrush);
    
    // Textfarbe und Hintergrund setzen und Text ausgeben
    SetBkColor(hdcBitmap, RGB(255, 0, 0));			// red text background
    SetTextColor(hdcBitmap, decor->GetFontColor()); // Write text with decorator color
    TextOut(hdcBitmap,0,0,decor->GetDecoratorText(),textLength);
    
    // Alphabitmap-Structure anlegen und füllen
    VMR9AlphaBitmap bmpInfo;
    ZeroMemory(&bmpInfo, sizeof(bmpInfo) );
    bmpInfo.dwFlags = VMRBITMAP_HDC;
    bmpInfo.hdc = hdcBitmap;  // DC which has selected our bitmap
    // Das Bitmap, welches exakt so groß ist wie das Video selbst, auf die ganze groesse skalieren
    // wobei keine groessenaenderung stattfindet, weil beides gleich gross ist
    bmpInfo.rDest.left	= 0.0f;
    bmpInfo.rDest.top	= 0.0f;
    bmpInfo.rDest.right	= 1.0f;
    bmpInfo.rDest.bottom	= 1.0f;
    bmpInfo.rSrc = videoWindowRect;
    bmpInfo.fAlpha = TRANSPARENCY_VALUE;
    
    // transparente Farbe definieren
    this->SetColorRef(bmpInfo);
    
    // das bitmap dem VMR9 bekanntgeben
    hr = pBMP->SetAlphaBitmap(&bmpInfo);
    

    Soweit mal der Codeausschnitt.

    Wenn ich das Bitmap nur so groß mache wie das Video groß ist (also die native Videogröße von 704x576), und es dann im bmpInfo im rSrc auch so angebe, dann wird das Bitmap "gestreched" und die Schrift verändert ihre Größe wie im Ticker-beispiel auch. Aber eben das soll nicht passieren. Deshalb auch der Ansatz, dass ich das Bitmap gleich so groß mache wie es später angezeigt werden soll und nix mehr skaliert werden muss. Aber irgendwas wird da scheinbar doch noch mit gemacht, auch wenn das Bitmap schon exakt so groß ist wie das, was der Renderer (VMR9) an Ausgabegröße hat.

    Ich weiß, das ist wieder sehr speziell. Aber ich such jetzt schon seit 3 Tagen im Netz und ich hab kein Beispiel gefunden das von vornherein ein so großes Bitmap benutzt. Alle Beispiele gehen davon aus, dass das Bitmap kleiner wie dienative Videogröße ist, und mit dem verändern der Anzeigegröße des Videos sich auch mit verändert. Und ich muss nunmal, egal wie groß das Video angezeigt wird, und in welchem Format, die Schrift immer gleich groß und in gleichbleibender (guter) Qualität haben.

    Würde mich freuen wenn da jemand nen Tipp für mich hat

    Gruß
    Alex



  • So, hab ich hab den "Schuldigen" gefunden:

    VMR9 ...

    Das zusammenfügen des Videobildes und es Overlays findet auf der Auflösungsebene statt, die am Input-Pin des VMR9 rein kommt. D.h. wenn ich ein Video mit 704x576 habe, kann das auf dem Bildschirm viel größer angezeigt werden, aber das Overlay-Bild wird auf 704x576 angepasst, mit dem Video gemixt und dann groß angezeigt.

    Das erklärt warum die Schrift zunehmend anfängt sch**sse auszusehen wenn mein Overlay-Bitmap größer als die native Video-Auflösung am Input-Pin des Renderers ist.

    Somit ist es mit dem VMR9 nicht möglich bei variierender Darstellungsauflösung eine gleichbleibende Schrift(größe) auf dem Overlay zu zeichnen.

    Naja, soweit sind das gute Nachrichten, weil ich mich dann in der Richtung nicht mehr weiter rumärgern muss. Auf der andere Seite sinds schlechte Nachrichten die ich jetzt meinem Chef übermitteln muss 😢

    - Alex


Anmelden zum Antworten