PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : GDI+ Graphics Objekt von Buffer Data?


Matrix316
2006-12-31, 16:10:00
Nehmen wir mal an ich habe einen TransInPlace Filter, der IMediaSample Samples bekommt.

Jetzt versuche ich auf jedes Frame einen Text zu schreiben, quasi overlay mäßig nur ohne Overlay. ;)

Bei google Groups habe ich eine einfache Lösung gefunden, aber irgendwie finde ich nirgends eine Anleitung wie das genau gehen soll.

Der Text geht ungefähr so:

I did this very successfully by using a TransInPlaceFilter
by creating a GDI+ Graphics object from the Bitmap data
in the sample buffer and then using GDI+ Drawstring functions
to write over the bitmap data.

Wie bekomm ich aus den Daten im Sample Buffer ein Bitmap? Größe der Frames habe ich. Bzw. wie mach ich ein Graphics Object aus den Daten?

MSDN sagt, ein Graphics Object kann ich mit einem Pointer auf ein Image bekommen Graphics::Graphics(Image*), aber wie mach ich aus den Daten im Sample Buffer ein Image? MSDN sagt, ein Image Objekt kann ich aus einem Stream und einem File laden: Image::Image(IStream*,BOOL)
Image::Image(WCHAR*,BOOL) Wie mach ich das aber mit meinen Daten im Buffer?

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/gdicpp/GDIPlus/GDIPlusreference/classes/graphics.asp
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/gdicpp/GDIPlus/GDIPlusreference/classes/image.asp

Bislang sieht der erste Versuch erstmal so aus:


HRESULT Transform(IMediaSample *pSample)
{

AM_MEDIA_TYPE* pType = NULL;
pSample->GetMediaType(&pType);
VIDEOINFOHEADER *pvi = (VIDEOINFOHEADER *) pType->pbFormat;
ASSERT(pvi);

BYTE *bVideo;
pSample->GetPointer(&bVideo);

int cxImage = pvi->bmiHeader.biWidth;
int cyImage = pvi->bmiHeader.biHeight;
int numPixels = cxImage * cyImage;

RGBTRIPLE *prgb = NULL;

Image *pBitmapImage = NULL; //

//bVideo zu Image ************** hier müssen irgendwie die Daten zu dem Image kommen, aber wie?

Graphics graphics(pBitmapImage);

SolidBrush brush(Color(255, 0, 0, 255));
FontFamily fontFamily(L"Times New Roman");
Font font(&fontFamily, 24, FontStyleRegular, UnitPixel);
PointF pointF(10.0f, 20.0f);

graphics.DrawString(L"Hello World!", -1, &font, pointF, &brush);

return NOERROR;
}


ODER gibts vielleicht noch eine einfachere Möglichkeit Text über ein Video zu legen, nur mit einem Filter? Also möglichst ohne VMR, Overlay Mixer und sowas?

Matrix316
2007-01-02, 16:21:24
Ok, ist das Thema zu einfach oder kennt sich nur keiner aus? ;)

Gast
2007-01-02, 18:34:13
Ok, ist das Thema zu einfach oder kennt sich nur keiner aus? ;)
Es kennt sich wahrscheinlich keiner damit aus. ;)
Ist ja schon ne spezielle Frage.

Mein Ansätze wären:
1. Versuchen ein ausgenommen der Schrift transparentes Bild einfach über dein Video drüberlegen. (irgendwie hab ich aber den Verdacht das wird nix; wäre aber einfach)
2.
-Schrift in Bild rendern (Bild möglichst klein wählen)
-Pointer vom Buffer holen
-Über "Schriftbild" drüberinterieren und überall, wo es nicht nicht transparent ist, den Buffer überschreiben.
-Wenn du noch das AA mitnutzen willst, kannst du auch noch den Alphawert einfließen lassen.

Wenns noch schneller sein soll und die Schrift konstant bleibt über längeren Zeitraum, kannst du dir noch nen Vector/Array (auf keinen Fall sowas wie Dictionary!) anlegen, in dem alle zu änderenden Positionen + RGBA-Wert drinstehen. Dann fällt noch das Iterieren über die vollkommen transparenten Pixel weg.

Kann natürlich auch sehr gut sein, dass einfacher geht. ;)

Matrix316
2007-01-02, 20:34:02
Mit einem GDI+ Graphics Objekt solls ja angeblich sehr einfach gehen...:wink:

Ich muss irgendwie die Bitmap Daten im Buffer als "Image" speichern.

Mit Overlay würde es sicher auch gehen, ich würde aber auf den VMR Render Filter verzichten.