Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C / C++ / MFC
  4. Drawing a bitmap on DC created by BYTE* array

Drawing a bitmap on DC created by BYTE* array

Scheduled Pinned Locked Moved C / C++ / MFC
graphicsdata-structuresperformancequestion
4 Posts 3 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • T Offline
    T Offline
    TalSt
    wrote on last edited by
    #1

    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:

    B D 2 Replies Last reply
    0
    • T TalSt

      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:

      B Offline
      B Offline
      Baltoro
      wrote on last edited by
      #2

      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

      1 Reply Last reply
      0
      • T TalSt

        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:

        D Offline
        D Offline
        Dan 0
        wrote on last edited by
        #3

        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);

        T 1 Reply Last reply
        0
        • D Dan 0

          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);

          T Offline
          T Offline
          TalSt
          wrote on last edited by
          #4

          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:

          1 Reply Last reply
          0
          Reply
          • Reply as topic
          Log in to reply
          • Oldest to Newest
          • Newest to Oldest
          • Most Votes


          • Login

          • Don't have an account? Register

          • Login or register to search.
          • First post
            Last post
          0
          • Categories
          • Recent
          • Tags
          • Popular
          • World
          • Users
          • Groups