xiaoluo Geschrieben 24. Mai 2008 Teilen Geschrieben 24. Mai 2008 Hallo erstmal, ich such schon die ganze Zeit nach einer Möglichkeit aus einem Bytearray ein Bitmap zu erzeugen. Bisher habe ich noch ncihts gefunden, bzw. waren die Links die ich woanders gefunden habe und durch selber suchen gefunden habe nicht gerade Hilfreich. Nun zu meinem Problem. Ich bekomme das LiveBild meiner Webcam. Die Bilddaten sind in der LPVIDEOHDR->lpData gespeichert. (Ich greife mit den Cap Treibern auf die Kamera zu). Ich manipuliere diese Bilddaten so, das nur noch GRauwerte enthalten sind. Und genau aus jenem Array möchte ich nun ein Bitmap erzeugen das ich in dem Dialog anzeigen lassen kann, an einer bestimmten Stelle. Da das ein Livebild ist, wird also ständig aus den Bilddaten das GRauwertbild berechnet und soll im Dialog angezeigt werden. Ich weiß, der Treiber bietet das schon mit an. Es geht darum zu überprüfen ob ich die Daten wirklih manipulieren kann. Arbeite an einer Bilderkennung. Habe diesen Codefetzen gefunden , aber der Hilft mir auch nciht weiter. LONG lImageWidth = 640; LONG lImageHeight = 480; WORD wBitsPerPixel = 8; LONG lBytesPerRow = (((lImageWidth * (long)wBitsPerPixel + 31L) & (~31L)) / 8L); BITMAPINFO *bm = (BITMAPINFO *)new BYTE[sizeof(BITMAPINFO) + 255 * sizeof(RGBQUAD)]; bm->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); bm->bmiHeader.biWidth = lImageWidth; bm->bmiHeader.biHeight = lImageHeight; bm->bmiHeader.biPlanes = 1; bm->bmiHeader.biBitCount = wBitsPerPixel; bm->bmiHeader.biCompression = BI_RGB; bm->bmiHeader.biSizeImage = 0; bm->bmiHeader.biXPelsPerMeter = 0; bm->bmiHeader.biYPelsPerMeter = 0; bm->bmiHeader.biClrUsed = 0; bm->bmiHeader.biClrImportant = 0; for (int color_index = 0; color_index < 256; color_index++) { bm->bmiColors[color_index].rgbBlue = color_index; bm->bmiColors[color_index].rgbGreen = color_index; bm->bmiColors[color_index].rgbRed = color_index; bm->bmiColors[color_index].rgbReserved = 0; } BYTE *pBitmapBits; HBITMAP hBitmap = ::CreateDIBSection(NULL, bm, DIB_RGB_COLORS, (void**)&pBitmapBits, NULL, 0); if (hBitmap) { ::DeleteObject(hBitmap); } delete[] (BYTE *)bm; Also, vielleicht hat hier jemand nen stück code für mich, wenns geht recht einfach. Vielleicht braucht man nichtmal ein bitmap zu erzeugen um die Daten auf dem Dialog anzuzeigen. Am besten etwas, für die OnPaint Methode. Grüße, xiaoluo Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Bubble Geschrieben 24. Mai 2008 Teilen Geschrieben 24. Mai 2008 Hallo erstmal, ich such schon die ganze Zeit nach einer Möglichkeit aus einem Bytearray ein Bitmap zu erzeugen. Wenn die Bitmap im Array bereits in einem Format vorliegt, dass Windows versteht, kannst Du die Bitmap mit StretchDIBits ausgeben lassen. Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
xiaoluo Geschrieben 24. Mai 2008 Autor Teilen Geschrieben 24. Mai 2008 Hallo und nein Die Daten liegen in einem Byte Array , sprich ein unsigned char Array. Daraus muss ich wie gesagt ein Bitmap erzeugen welches ich dann benutzen kann. Grüße, xiaoluo Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Bubble Geschrieben 25. Mai 2008 Teilen Geschrieben 25. Mai 2008 Die Daten liegen in einem Byte Array , sprich ein unsigned char Array. Die Daten in dem Array enthalten bereits die Bits der Bitmap. Idealerweise muss hier nichts mehr umgewandelt werden. Zusätzlich müssen zur Darstellung beschreibende Informationen übergeben werden (unter anderem Pixelformat, Auflösung, ...). Daraus muss ich wie gesagt ein Bitmap erzeugen welches ich dann benutzen kann. Wenn die Daten in einem geeigneten Format vorliegen (unterstützte Varianten siehe BITMAPINFOHEADER), dann können sie mit der von mir bereits genannten Funktion in einen device context gezeichnet werden. Dazu ist eine BITMAPINFO Struktur anzulegen und auszufüllen und ein paar weitere Parameter müssen übergeben werden. Wenn Du mit den Video Capture Funktionen arbeitest, solltest Du mit Hilfe einer dieser Funktionen eine ausgefüllte BITMAPINFO Struktur erhalten können. Wenn das Format der Daten nicht unterstützt wird, dann müssen sie zur Darstellung in ein unterstütztes Format umgewandelt werden. Solange es aber keinerlei Informationen über das verwendete Pixelformat (Datenformat im Array aus Bytes) gibt, kann man dazu aus der Ferne wenig sagen. Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
xiaoluo Geschrieben 25. Mai 2008 Autor Teilen Geschrieben 25. Mai 2008 Guten Morgn, danke erstmal füpr die schnellen Antworten. Sobal ein neues Bild von der Kamera kommt, wird eine Callbackfunktion aufgerufen. Dieser wird dann ein Zeiger auf eine LPVIDEOHDR Strukturübergeben. Diese enthält folgende Elemente dwBufferLength; dwBytesUsed; dwFlags; dwReserved; dwTimeCaptured; dwUser; lpData; Wichtig ist hier nur die Bufferlength, also wieviel Bytes enthalten sind. Bei mir sind es 921600 Byte (640 * 480 * 3). lpData ist ein Zeiger auf das ByteArray. Könntest du mir bitte ein Stück Code geben ? Ich habe bisher nur so etwas in der OnPaint stehen if(isIconic) { ... ... } else { CPaintDC dc(this); CDC cdc; CRecr rect; m_IDCGreyView.GetWindowRect(&rect); ScreenToClient(&rect); m_HBitmap = CreateBitmapFromPixel(::GetDC(this->GetSafeHwnd ()),rect.Width(),rect.Height(),3,&m_pBuffer); memDC.SelectObject(CBitmap::FromHandle(m_HBitmap)); dc.BitBlt(rect.TopLeft().x,rect.TopLeft().y,rect.Width(),rect.Height (),&memDC,0,0,SRCCOPY); } Aber das Funktioniert nicht. Währe wirklcih Dankbar, wenn ich hier nen kleines Codebeispiel bekomemn könnte. Ich hänge schon ein paar Tage an diesem Problem. Nen normales Bitmap aus einer Datei laden und Anzeigen ist kein Problem, aber den Inhalt des ByteArrays im Dialog anzeigen schon (für michjedenfalls). Grüße, xiaoluo Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
gerhins Geschrieben 21. Oktober 2009 Teilen Geschrieben 21. Oktober 2009 Hallo, ich habe das gleiche Problem ! Hast du schon rausgekriegt wie's geht ? danke im Voraus Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
xiaoluo Geschrieben 21. Oktober 2009 Autor Teilen Geschrieben 21. Oktober 2009 Ja, das geht. Ist ja auch schon wieder über ein Jahr her Soweit ich das in Erinnerung habe legst du dir eine Variable vom Typ HBitmap an. HBitmap hBmp = CreateDDBFromPixel(hDC, width, height, bpp, NULL); Mit NULL am Ende, reservierst du quasi den Speicher schonmal. HBITMAP CreateDDBFromPixel( HDC hDC, UINT uWidth, UINT uHeight, UINT uBitsPerPixel, LPVOID pBits ) { HBITMAP HBitmap = NULL; if ( !uWidth || !uHeight || !uBitsPerPixel ) { return HBitmap; } LONG lBmpSize = uWidth * uHeight * uBitsPerPixel / 8; BITMAPINFO bmpInfo = { 0 }; bmpInfo.bmiHeader.biBitCount = uBitsPerPixel; bmpInfo.bmiHeader.biHeight = uHeight; bmpInfo.bmiHeader.biWidth = uWidth; bmpInfo.bmiHeader.biPlanes = 1; bmpInfo.bmiHeader.biSizeImage = uWidth * uHeight * (uBitsPerPixel / 8); bmpInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); bmpInfo.bmiHeader.biCompression = BI_RGB; // Pointer to access the pixels of bitmap UINT * pPixels = NULL; HBitmap = CreateDIBitmap(hDC,(BITMAPINFOHEADER*)&bmpInfo.bmiHeader,CBM_INIT, pBits,(BITMAPINFO*)&bmpInfo,DIB_RGB_COLORS); if (!HBitmap) { return HBitmap;//hBitmap; // return if invalid bitmaps } return HBitmap; } Um dann das Bild in zu zeichen, sollte das glaueb ich so ablaufen... OnPaint - Methode { CPaintDC dc(this); dc.SetStretchBltMode(COLORONCOLOR); unsigned char* pBuffer = DEIN_BUFFER // set bitmap bits into bitmap ::SetDIBits(NULL,hBmp,0,480,pBuffer,&Bitmapinfo,DIB_RGB_COLORS); CBitmap* pBitmap = CBitmap::FromHandle(hBmp); CDC cdc; cdc.CreateCompatibleDC(&dc); //CBitmap bitmap; CBitmap* pOldBitmap = cdc.SelectObject(pBitmap); dc.BitBlt(rect.TopLeft().x,rect.TopLeft().y,rect.Width(),rect.Height(),&cdc,0,0,SRCCOPY); cdc.SelectObject(pOldBitmap); ReleaseDC(&cdc); cdc.DeleteDC(); CDialog::OnPaint(); } Ok, dann viel Spaß beim Probieren. Grüße, xiaoluo Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
gerhins Geschrieben 23. Oktober 2009 Teilen Geschrieben 23. Oktober 2009 Danke für die schnelle Antwort ! Ich hab jetzt noch was anderes gefunden: Mit den beiden Funktionen " CreateCompatibleBitmap(...)" und "SetBitmapBits(...)" geht's auch ganz einfach. ich hab auch mal gelesen, dass ein DIBBitmap sehr viel langsamer sein soll. int Breite=640; int Hoehe=480; CBitmap bitmap; int Farbtiefe=32; BYTE bits[xxx];// xxx = Breite*Hoehe*4 bitmap.CreateCompatibleBitmap(pDC,Breite,Hoehe); bitmap.SetBitmapBits(Farbtiefe,&bits); Grüße Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
xiaoluo Geschrieben 23. Oktober 2009 Autor Teilen Geschrieben 23. Oktober 2009 Hallo, alle Wege führen nach Rom. Für mich war das damals die passenste Möglichkeit der Umwandlung. DDB steht dabei für device dependet und DIB für device independent. Da gibts auch große Unterschiede. Ich hoffe, es funktioniert jetzt alles bei dir. Das HBITMAP habe ich nur einmal erzeugt, und dann immer nur die Pixel, also den Puffer, ersetzt. Ich habe das für ein Capturing gebraucht, da ist es sehr ungünstig jedesmal pro Frame ein HBITMAP zu erzeugen und nach Darstellung zu löschen. Grüße, xiaoluo Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Empfohlene Beiträge
Dein Kommentar
Du kannst jetzt schreiben und Dich später registrieren. Wenn Du ein Konto hast, melde Dich jetzt an, um unter Deinem Benutzernamen zu schreiben.