Zum Inhalt springen

bytearray zu Bitmap


xiaoluo

Empfohlene Beiträge

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

Link zu diesem Kommentar
Auf anderen Seiten teilen

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.

Link zu diesem Kommentar
Auf anderen Seiten teilen

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

Link zu diesem Kommentar
Auf anderen Seiten teilen

  • 1 Jahr später...

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

Link zu diesem Kommentar
Auf anderen Seiten teilen

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

Link zu diesem Kommentar
Auf anderen Seiten teilen

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

Link zu diesem Kommentar
Auf anderen Seiten teilen

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.

Gast
Auf dieses Thema antworten...

×   Du hast formatierten Text eingefügt.   Formatierung wiederherstellen

  Nur 75 Emojis sind erlaubt.

×   Dein Link wurde automatisch eingebettet.   Einbetten rückgängig machen und als Link darstellen

×   Dein vorheriger Inhalt wurde wiederhergestellt.   Editor leeren

×   Du kannst Bilder nicht direkt einfügen. Lade Bilder hoch oder lade sie von einer URL.

Fachinformatiker.de, 2024 by SE Internet Services

fidelogo_small.png

Schicke uns eine Nachricht!

Fachinformatiker.de ist die größte IT-Community
rund um Ausbildung, Job, Weiterbildung für IT-Fachkräfte.

Fachinformatiker.de App

Download on the App Store
Get it on Google Play

Kontakt

Hier werben?
Oder sende eine E-Mail an

Social media u. feeds

Jobboard für Fachinformatiker und IT-Fachkräfte

×
×
  • Neu erstellen...