CreateDIBSection
-
den MSDN eintrag kenne ich natürlich schon.
pbmi besteht aus dem Header (den du schon vernünftig gefüllt hast - nur in biSizeImage sollte die Länge des BYTE-Bereiches stehen)
nWidth*nHeight*3 ist doch die länge meines byte arrays...
hdc wird offenbar nur gebraucht, wenn du iUsage auf DIB_PAL_COLORS setzt, du kannst es dir z.B. mit GetDC besorgen.
wie denn? ich kann mir unter diesen handles immer gar nicht so richtiges vorstellen, haben die was mit meinem Dialog zu tun?
HDC hdc = GetDC(NULL);
funktioniert nicht
BmpInfo.bmiColors=NULL;
funktioniert ebenfalls nicht
-
BitmapDIBUncompressed32Bit.h:
//------------------------------------------------------------------------------ // Last Change: 8-10-2005 // Author: Julian Amann (vertexwahn@gmx.de) // // Brief description: simple class to handle 32 bit uncompressed bitmaps for // windows //------------------------------------------------------------------------------ #ifndef BitmapDIBUncompressed32Bit_h #define BitmapDIBUncompressed32Bit_h #include <windows.h> #include <stdio.h> #ifdef _MSC_VER #pragma pack(push,packing) #pragma pack(1) #define PACK_STRUCT #else #error you must byte-align these structures with appropriate compiler directives #endif //------------------------------------------------------------------------------------ // a class for an uncompressed bitmap class BitmapDIBUncompressed32Bit { public: BitmapDIBUncompressed32Bit(char * filename); BitmapDIBUncompressed32Bit(HDC hdc, int width, int height); int getWidth() const; int getHeight() const; void Save(char * filename); virtual ~BitmapDIBUncompressed32Bit(); void Release(); HDC getHDC(); UINT * getBytes() const; void setBytes(UINT * data) { BitmapBytes = data; } private: BitmapDIBUncompressed32Bit(const BitmapDIBUncompressed32Bit &src) {}; UINT *BitmapBytes; BITMAPINFO BitmapInfo; BITMAPINFOHEADER BitmapInfoHeader; HDC BitmapHDC; HBITMAP BitmapHandle; }; void CaptureScreen(BitmapDIBUncompressed32Bit &bitmap); // force default byte alignment #ifdef _MSC_VER #pragma pack(pop, packing) #endif #undef PACK_STRUCT #endif
BitmapDIBUncompressed32Bit.cpp:
//------------------------------------------------------------------------------ // Last Change: 8-10-2005 // Author: Julian Amann (vertexwahn@gmx.de) // // Brief description: simple class to handle 32 bit uncompressed bitmaps for // windows //------------------------------------------------------------------------------ #include <windows.h> #include <stdio.h> #include "BitmapDIBUncompressed32Bit.h" #ifdef _MSC_VER #pragma pack(push,packing) #pragma pack(1) #define PACK_STRUCT #else #error you must byte-align these structures with appropriate compiler directives #endif BitmapDIBUncompressed32Bit::BitmapDIBUncompressed32Bit(char * filename) { HBITMAP hBitmap = (HBITMAP)LoadImage(NULL, filename, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE|LR_CREATEDIBSECTION); if(hBitmap==0) MessageBox(NULL,"","",MB_OK); BITMAP Bitmap; GetObject(hBitmap, sizeof(BITMAP), &Bitmap); HDC tmpBitmapHDC = CreateCompatibleDC(0); SelectObject(tmpBitmapHDC, hBitmap); BitmapInfoHeader.biSize = sizeof(BitmapInfo); BitmapInfoHeader.biWidth = Bitmap.bmWidth; BitmapInfoHeader.biHeight = Bitmap.bmHeight; BitmapInfoHeader.biCompression = BI_RGB; BitmapInfoHeader.biBitCount = 32; BitmapInfoHeader.biPlanes = 1; BitmapInfoHeader.biSizeImage = 0; BitmapInfoHeader.biClrImportant = 0; BitmapInfoHeader.biClrUsed = 0; BitmapInfoHeader.biSizeImage = 0; BitmapInfoHeader.biXPelsPerMeter = 0; BitmapInfoHeader.biYPelsPerMeter = 0; BitmapInfo.bmiHeader = BitmapInfoHeader; BitmapHDC = CreateCompatibleDC(0); BitmapHandle = CreateDIBSection(0, &BitmapInfo, 0, (void**)&BitmapBytes, NULL, 0); SelectObject(BitmapHDC, BitmapHandle); BitBlt(BitmapHDC, 0, 0, Bitmap.bmWidth, Bitmap.bmHeight, tmpBitmapHDC, 0, 0, SRCCOPY); DeleteObject(hBitmap); } BitmapDIBUncompressed32Bit::BitmapDIBUncompressed32Bit(HDC hdc, int width, int height) { BitmapInfoHeader.biSize = sizeof(BitmapInfo); BitmapInfoHeader.biWidth = width; BitmapInfoHeader.biHeight = height; BitmapInfoHeader.biCompression = BI_RGB; BitmapInfoHeader.biBitCount = 32; BitmapInfoHeader.biPlanes = 1; BitmapInfoHeader.biSizeImage = 0; BitmapInfoHeader.biClrImportant = 0; BitmapInfoHeader.biClrUsed = 0; BitmapInfoHeader.biSizeImage = 0; BitmapInfoHeader.biXPelsPerMeter = 0; BitmapInfoHeader.biYPelsPerMeter = 0; BitmapInfo.bmiHeader = BitmapInfoHeader; BitmapHDC = CreateCompatibleDC(hdc); BitmapHandle = CreateDIBSection(hdc, &BitmapInfo, 0, (void**)&BitmapBytes, NULL, 0); SelectObject(BitmapHDC, BitmapHandle); } int BitmapDIBUncompressed32Bit::getWidth() const { return BitmapInfoHeader.biWidth; } int BitmapDIBUncompressed32Bit::getHeight() const { return BitmapInfoHeader.biHeight; } void BitmapDIBUncompressed32Bit::Save(char * filename) { int imagesize = getWidth() * getHeight() * 4; BITMAPFILEHEADER BitmapFileHeader; // File Header BitmapFileHeader.bfType = 0x4D42; // Signatur 0x4D42 (="BM") BitmapFileHeader.bfSize = sizeof(BITMAPFILEHEADER) + // Gesamtgröße der Datei in Bytes sizeof(BITMAPINFOHEADER) + imagesize; BitmapFileHeader.bfReserved1 = 0; // immer 0 BitmapFileHeader.bfReserved2 = 0; // immer 0 BitmapFileHeader.bfOffBits = 54; // Offset der Pixeldaten innerhalb der Datei (bei uncompressed 32 bit immer 54 Bytes) BITMAPINFOHEADER BitmapInfoHeader; // Bitmap Info Header BitmapInfoHeader.biSize = sizeof(BITMAPINFOHEADER); // Größe der Struktur in Bytes (40) BitmapInfoHeader.biWidth = getWidth(); // Breite des Bildes in Pixel BitmapInfoHeader.biHeight = getHeight(); // Höhe des Bildes in Pixel BitmapInfoHeader.biPlanes = 1; // = 1 BitmapInfoHeader.biBitCount = 32; // 32 Bits Pro Pixel BitmapInfoHeader.biCompression = BI_RGB; // Komprimierung (0 = keine) BitmapInfoHeader.biSizeImage = imagesize; // Umfang der Pixeldaten in Bytes BitmapInfoHeader.biXPelsPerMeter = 0; // horizontale Auflösung (Pixel pro Meter) BitmapInfoHeader.biYPelsPerMeter = 0; // vertikale Aufläsung (Pixel pro Meter) BitmapInfoHeader.biClrUsed = 0; // Zahl der verwendeten Farben BitmapInfoHeader.biClrImportant = 0; // Zahl der wichtigen Farben FILE *ptrFile = NULL; ptrFile = fopen(filename, "wb"); fwrite(&BitmapFileHeader, sizeof(BITMAPFILEHEADER), 1, ptrFile); fwrite(&BitmapInfoHeader, sizeof(BITMAPINFOHEADER), 1, ptrFile); fwrite(BitmapBytes, getWidth() * getHeight() * 4, 1, ptrFile); fclose(ptrFile); } BitmapDIBUncompressed32Bit::~BitmapDIBUncompressed32Bit() { Release(); } void BitmapDIBUncompressed32Bit::Release() { DeleteObject(BitmapHandle); } HDC BitmapDIBUncompressed32Bit::getHDC() { return BitmapHDC; } UINT * BitmapDIBUncompressed32Bit::getBytes() const { return BitmapBytes; } void CaptureScreen(BitmapDIBUncompressed32Bit &bitmap) { HDC hdcDesktop = GetWindowDC(GetDesktopWindow()); BitBlt(bitmap.getHDC(), 0, 0, bitmap.getWidth(), bitmap.getHeight(), hdcDesktop, 0, 0, SRCCOPY); } // force default byte alignment #ifdef _MSC_VER #pragma pack(pop, packing) #endif #undef PACK_STRUCT
-
HBITMAP hBitmap; BITMAP Bitmap; HDC tmpBitmapHDC; BYTE *pBGRData; BITMAPINFO BitmapInfo; BITMAPINFOHEADER BitmapInfoHeader; HDC BitmapHDC; HBITMAP BitmapHandle; hBitmap = (HBITMAP)LoadImage(NULL,m_csCurrentDir+m_csCurrentFile, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE|LR_CREATEDIBSECTION); GetObject(hBitmap, sizeof(BITMAP), &Bitmap); tmpBitmapHDC = CreateCompatibleDC(0); SelectObject(tmpBitmapHDC, hBitmap); BitmapInfoHeader.biSize = sizeof(BitmapInfo); BitmapInfoHeader.biWidth = Bitmap.bmWidth; BitmapInfoHeader.biHeight = Bitmap.bmHeight; BitmapInfoHeader.biCompression = BI_RGB; BitmapInfoHeader.biBitCount = 24; BitmapInfoHeader.biPlanes = 1; BitmapInfoHeader.biSizeImage = 0; BitmapInfoHeader.biClrImportant = 0; BitmapInfoHeader.biClrUsed = 0; BitmapInfoHeader.biSizeImage = 0; BitmapInfoHeader.biXPelsPerMeter = 0; BitmapInfoHeader.biYPelsPerMeter = 0; BitmapInfo.bmiHeader = BitmapInfoHeader; BitmapHDC = CreateCompatibleDC(0); BitmapHandle = CreateDIBSection(0, &BitmapInfo,0, (void**)&pBGRData, NULL, 0);
müsste nach dem ich diesen code abarbeite, nicht eigentlich die BGR-Farbdaten in meinem pBGRData liegen? es scheint nicht so ... wie bekomm ich die dort rein? vielleicht irgendwie mit GetDIBits(...)
mfg, TFTS
-
UINT * BitmapDIBUncompressed32Bit::getBytes() const { return BitmapBytes; }
wenn du ein Pixel ändern willst gehst du wie folgt vor:
UINT data =BMP.getBytes(); data[x+y*BMP.getHeight()] = 0xFFFF0000; // Setzt Pixel auf rot
-
müsste nach dem ich diesen code abarbeite, nicht eigentlich die BGR-Farbdaten in meinem pBGRData liegen?
yup - das tuen sie auch!
einfach mal pBGRData[0] = 43545; schon hast du die Farbe des ersten Pixels verändert
-
ah moment...vielleicht liegt es daran, warum es nicht bei mir funktioniert:
ich hab es ja jetzt als BYTE Pointer definiert, ein BYTE hat natürlich nur 256 Werte... werden die pixel etwa nicht als RGB zurückgegeben, also jeder kanal einzeln sondern als ein Farbwert zwischen 0 und 65535? ... ich bräuchte es ja als RGB ...mfg, TFTS
noch etwas... ich möchte die bilder gern auf meinem Dialog darstellen. Bis jetzt hab ich das über ein CBitmap Objekt gemacht. Kann ich denn irgendwie diese ganzen variablen in ein CBitmap Objekt packen? ich hab es mit FromHandle(hBitmap) und mit FromHandle(BitmapHandle) versucht ... ging beides nich
und so verwende ich dann das CBitmap zum zeichnen... die Daten werden an ein CDC Pointer übergeben. In der OnPaint Fkt wird dann der CDC pointer per BitBlt bzw. StretchBlt auf den Dialog gebracht
m_pVirtualDC->SelectObject(pCBitmap); //m_pBitmap=pCBitmap; pCBitmap->DeleteObject(); m_bDrawPicture = true; CPicConvert::GetStretchDimension(m_nCurrentWidth,m_nCurrentHeight,m_nMaxWidth,m_nMaxHeight,&m_nStretchedWidth,&m_nStretchedHeight); //Aufruf der OnPaint... //this->Invalidate(); CRect crPicRect; if(((m_bScale && m_bScaleNeeded) || !m_bScaleNeeded) && m_bStretchToMax) crPicRect.SetRect(m_nHScrollPos+m_nXPicOffset,m_nVScrollPos+m_nYPicOffset,m_nHScrollPos+m_nXPicOffset+m_nStretchedWidth,m_nVScrollPos+m_nYPicOffset+m_nStretchedHeight); else crPicRect.SetRect(m_nHScrollPos+m_nXPicOffset,m_nVScrollPos+m_nYPicOffset,m_nHScrollPos+m_nXPicOffset+m_nCurrentWidth, m_nVScrollPos+m_nYPicOffset+m_nCurrentHeight); this->InvalidateRect(crPicRect,true);
-
BitmapInfoHeader.biBitCount = 32; // 32 Bits Pro Pixel
hier lege ich fest, das ich eine Farbtiefe von 32 Bit Benutzen möchte
folgende anordnung:
0xAARRGGBB
-
bei den MFC spezifischen Sachen solltest du vielleicht mal im MFC Forum nachfragen
-
meine erste frage war eigentlich nicht mfc spezifisch. wie bekomme ich denn aus dem UINT die einzelnen Farbwerte (Rot Grün Blau) auf meinen BYTE Vektor ... der byte vektor müsste ja dann die 3-fache länge des UINT Vektors haben, oder?
also was ich eigentlich wissen will ist, ob das hier funktioniert,
BitmapHandle = CreateDIBSection(0, &BitmapInfo,0, (void**)&pBGRData, NULL, 0);
wenn es sich bei pBGRData um einen BYTE Pointer handelt.
mfg, TFTS
-
wie bekomme ich denn aus dem UINT die einzelnen Farbwerte (Rot Grün Blau) auf meinen BYTE Vektor ...
durch Bitmasken
vielleicht hilft dir auch folgendes:
Tutorial über das BMP Format:
http://turing.fh-landshut.de/~jamann/Das BMP Format.html
Demoprogramm, das DibCreateSection verwendet:
http://turing.fh-landshut.de/~jamann/Tunnel Effect.zip