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


Anmelden zum Antworten