Drawing a bitmap on DC created by BYTE* array
-
I wrote the following lines in order to draw a bitamp on DC created by BYTE* array: #define BPP 32 // Initialize the bitmapinfo header int nBitmapInfoSize = sizeof(BITMAPINFOHEADER) ; memset(&m_bitmapInfo, 0, m_nBitmapInfoSize); // Save size for drawing later. int nBitPP = BPP / 8; int nImageWidth = nWidth; int nImageHeight = nHeight; int nImageSize = nImageWidth * nImageHeight * nBitPP; // Allocate memory for byte array and initialize it BYTE* pbtImageArray = new BYTE [nImageSize]; memset(m_pbtImageArray, 0x0000, nImageSize); for (int i = 0; i < nImageSize - nBitPP; i+=nBitPP) { pbtImageArray[i] = 0x0000; pbtImageArray[i+1] = 0x0000; pbtImageArray[i+2] = 255; pbtImageArray[i+3] = 0x0000; } // Populate bitmapinfo header BITMAPINFO bitmapInfo; // Bitmap info bitmapInfo.bmiHeader.biSize = nBitmapInfoSize; bitmapInfo.bmiHeader.biWidth = nImageWidth; bitmapInfo.bmiHeader.biHeight = nImageHeight; bitmapInfo.bmiHeader.biPlanes = 1; bitmapInfo.bmiHeader.biBitCount = BPP; bitmapInfo.bmiHeader.biSizeImage = nImageSize; bitmapInfo.bmiHeader.biCompression = BI_RGB; // Create bitamp HBITMAP hbmp = CreateDIBSection( pCDC->GetSafeHdc(), &bitmapInfo, DIB_RGB_COLORS, (void**)pbtImageArray, NULL, 0); HDC hBitmapDC = CreateCompatibleDC(pCDC->GetSafeHdc() ); HBITMAP hOldBitmap = (HBITMAP)SelectObject(hBitmapDC, hbmp); StretchBlt( pCDC->GetSafeHdc(), nWindowX, nWindowY, nWindowWidth, nWindowHeight, // Destination hBitmapDC , nRegionX, nRegionY, nRegionWidth, nRegionHeight, // Source SRCCOPY); SelectObject(m_hBitmapDC, hOldBitmap); Do you know why this draw black image and not my BYTE* array? Thanks!:rose:
-
I wrote the following lines in order to draw a bitamp on DC created by BYTE* array: #define BPP 32 // Initialize the bitmapinfo header int nBitmapInfoSize = sizeof(BITMAPINFOHEADER) ; memset(&m_bitmapInfo, 0, m_nBitmapInfoSize); // Save size for drawing later. int nBitPP = BPP / 8; int nImageWidth = nWidth; int nImageHeight = nHeight; int nImageSize = nImageWidth * nImageHeight * nBitPP; // Allocate memory for byte array and initialize it BYTE* pbtImageArray = new BYTE [nImageSize]; memset(m_pbtImageArray, 0x0000, nImageSize); for (int i = 0; i < nImageSize - nBitPP; i+=nBitPP) { pbtImageArray[i] = 0x0000; pbtImageArray[i+1] = 0x0000; pbtImageArray[i+2] = 255; pbtImageArray[i+3] = 0x0000; } // Populate bitmapinfo header BITMAPINFO bitmapInfo; // Bitmap info bitmapInfo.bmiHeader.biSize = nBitmapInfoSize; bitmapInfo.bmiHeader.biWidth = nImageWidth; bitmapInfo.bmiHeader.biHeight = nImageHeight; bitmapInfo.bmiHeader.biPlanes = 1; bitmapInfo.bmiHeader.biBitCount = BPP; bitmapInfo.bmiHeader.biSizeImage = nImageSize; bitmapInfo.bmiHeader.biCompression = BI_RGB; // Create bitamp HBITMAP hbmp = CreateDIBSection( pCDC->GetSafeHdc(), &bitmapInfo, DIB_RGB_COLORS, (void**)pbtImageArray, NULL, 0); HDC hBitmapDC = CreateCompatibleDC(pCDC->GetSafeHdc() ); HBITMAP hOldBitmap = (HBITMAP)SelectObject(hBitmapDC, hbmp); StretchBlt( pCDC->GetSafeHdc(), nWindowX, nWindowY, nWindowWidth, nWindowHeight, // Destination hBitmapDC , nRegionX, nRegionY, nRegionWidth, nRegionHeight, // Source SRCCOPY); SelectObject(m_hBitmapDC, hOldBitmap); Do you know why this draw black image and not my BYTE* array? Thanks!:rose:
When doing this type of drawing for the first time and getting errors, you should check your return values, especially for CreateDIBSection. This can indicate where the problem occurs. I would also provide values for all the fields in the BITMAPINFO header structure. I'm assuming that all the other variables that you didn't explain, are correctly initialized values of some MFC class that you are using, and that the values are correct. I don't use MFC, but you might read this: Drawing a View[^] The article states: "A device context is a Windows data structure that contains information about the drawing attributes of a device such as a display or a printer. All drawing calls are made through a device-context object. For drawing on the screen, OnDraw is passed a CPaintDC object. For drawing on a printer, it is passed a CDC object set up for the current printer."
modified on Sunday, May 18, 2008 6:27 PM
-
I wrote the following lines in order to draw a bitamp on DC created by BYTE* array: #define BPP 32 // Initialize the bitmapinfo header int nBitmapInfoSize = sizeof(BITMAPINFOHEADER) ; memset(&m_bitmapInfo, 0, m_nBitmapInfoSize); // Save size for drawing later. int nBitPP = BPP / 8; int nImageWidth = nWidth; int nImageHeight = nHeight; int nImageSize = nImageWidth * nImageHeight * nBitPP; // Allocate memory for byte array and initialize it BYTE* pbtImageArray = new BYTE [nImageSize]; memset(m_pbtImageArray, 0x0000, nImageSize); for (int i = 0; i < nImageSize - nBitPP; i+=nBitPP) { pbtImageArray[i] = 0x0000; pbtImageArray[i+1] = 0x0000; pbtImageArray[i+2] = 255; pbtImageArray[i+3] = 0x0000; } // Populate bitmapinfo header BITMAPINFO bitmapInfo; // Bitmap info bitmapInfo.bmiHeader.biSize = nBitmapInfoSize; bitmapInfo.bmiHeader.biWidth = nImageWidth; bitmapInfo.bmiHeader.biHeight = nImageHeight; bitmapInfo.bmiHeader.biPlanes = 1; bitmapInfo.bmiHeader.biBitCount = BPP; bitmapInfo.bmiHeader.biSizeImage = nImageSize; bitmapInfo.bmiHeader.biCompression = BI_RGB; // Create bitamp HBITMAP hbmp = CreateDIBSection( pCDC->GetSafeHdc(), &bitmapInfo, DIB_RGB_COLORS, (void**)pbtImageArray, NULL, 0); HDC hBitmapDC = CreateCompatibleDC(pCDC->GetSafeHdc() ); HBITMAP hOldBitmap = (HBITMAP)SelectObject(hBitmapDC, hbmp); StretchBlt( pCDC->GetSafeHdc(), nWindowX, nWindowY, nWindowWidth, nWindowHeight, // Destination hBitmapDC , nRegionX, nRegionY, nRegionWidth, nRegionHeight, // Source SRCCOPY); SelectObject(m_hBitmapDC, hOldBitmap); Do you know why this draw black image and not my BYTE* array? Thanks!:rose:
Mostly your order is wrong, you do not need to allocate the byte array, CreateDIBSection does that for you, the pbtImageArray pointer you are passing in is the output, not the input So more along the lines of
#define BPP 32
int nBitPP = BPP / 8;
int nImageWidth = nWidth;
int nImageHeight = nHeight;
int nImageSize = nImageWidth * nImageHeight * nBitPP;// Populate bitmapinfo header
BITMAPINFO bitmapInfo; // Bitmap info
bitmapInfo.bmiHeader.biSize = nBitmapInfoSize;
bitmapInfo.bmiHeader.biWidth = nImageWidth;
bitmapInfo.bmiHeader.biHeight = nImageHeight;
bitmapInfo.bmiHeader.biPlanes = 1;
bitmapInfo.bmiHeader.biBitCount = BPP;
bitmapInfo.bmiHeader.biSizeImage = nImageSize;
bitmapInfo.bmiHeader.biCompression = BI_RGB;// Create dib
BYTE* pbtImageArray = NULL;
HBITMAP hbmp = CreateDIBSection( pCDC->GetSafeHdc(), &bitmapInfo, DIB_RGB_COLORS, (void**)&pbtImageArray, NULL, 0);//Then fill in the data.
for (int i = 0; i < nImageSize - nBitPP; i+=nBitPP)
{
pbtImageArray[i] = 0x0000;
pbtImageArray[i+1] = 0x0000;
pbtImageArray[i+2] = 255;
pbtImageArray[i+3] = 0x0000;
}
HDC hBitmapDC = CreateCompatibleDC(pCDC->GetSafeHdc() );HBITMAP hOldBitmap = (HBITMAP)SelectObject(hBitmapDC, hbmp);
StretchBlt( pCDC->GetSafeHdc(),
nWindowX, nWindowY,
nWindowWidth, nWindowHeight, // Destination
hBitmapDC ,
nRegionX, nRegionY,
nRegionWidth, nRegionHeight, // Source
SRCCOPY);SelectObject(m_hBitmapDC, hOldBitmap);
-
Mostly your order is wrong, you do not need to allocate the byte array, CreateDIBSection does that for you, the pbtImageArray pointer you are passing in is the output, not the input So more along the lines of
#define BPP 32
int nBitPP = BPP / 8;
int nImageWidth = nWidth;
int nImageHeight = nHeight;
int nImageSize = nImageWidth * nImageHeight * nBitPP;// Populate bitmapinfo header
BITMAPINFO bitmapInfo; // Bitmap info
bitmapInfo.bmiHeader.biSize = nBitmapInfoSize;
bitmapInfo.bmiHeader.biWidth = nImageWidth;
bitmapInfo.bmiHeader.biHeight = nImageHeight;
bitmapInfo.bmiHeader.biPlanes = 1;
bitmapInfo.bmiHeader.biBitCount = BPP;
bitmapInfo.bmiHeader.biSizeImage = nImageSize;
bitmapInfo.bmiHeader.biCompression = BI_RGB;// Create dib
BYTE* pbtImageArray = NULL;
HBITMAP hbmp = CreateDIBSection( pCDC->GetSafeHdc(), &bitmapInfo, DIB_RGB_COLORS, (void**)&pbtImageArray, NULL, 0);//Then fill in the data.
for (int i = 0; i < nImageSize - nBitPP; i+=nBitPP)
{
pbtImageArray[i] = 0x0000;
pbtImageArray[i+1] = 0x0000;
pbtImageArray[i+2] = 255;
pbtImageArray[i+3] = 0x0000;
}
HDC hBitmapDC = CreateCompatibleDC(pCDC->GetSafeHdc() );HBITMAP hOldBitmap = (HBITMAP)SelectObject(hBitmapDC, hbmp);
StretchBlt( pCDC->GetSafeHdc(),
nWindowX, nWindowY,
nWindowWidth, nWindowHeight, // Destination
hBitmapDC ,
nRegionX, nRegionY,
nRegionWidth, nRegionHeight, // Source
SRCCOPY);SelectObject(m_hBitmapDC, hOldBitmap);
Thanks! You are right, pbtImageArray is OUTPUT and not input. I change it to void* pbtImageArray and add: m_pbtImageArray = (BYTE*)pbtImageArray; As for the previuse reply: 1) Off course at my original code I add nResult and do all the checks!!! 2) I add initialization for all variables at bitmapinfo. Thanks you both! :laugh: :-D :) :rose: