Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: GetDIBits and LoadFromPixels incompatible  (Read 2060 times)

0 Members and 1 Guest are viewing this topic.

hippocat

  • Newbie
  • *
  • Posts: 17
    • View Profile
GetDIBits and LoadFromPixels incompatible
« on: March 02, 2010, 06:03:39 pm »
Hi,
I have ACTIVEX object that generates map, it works like:
Code: [Select]
map.Output(CDC);
I' d like to use this CDC as background for future painting. So in my InitailUpdate I do this:

Code: [Select]
   // Init OpenGL
    sf::WindowSettings st;
    st.AntialiasingLevel = 8;  // Make smooth drawing
    m_pSfmlView = new sf::RenderWindow(GetSafeHwnd(), st);


In OnDraw:

Code: [Select]
   m_map.Output(&m_WorkDC);

    BITMAPINFOHEADER bi;
    ::ZeroMemory(&bi, sizeof(BITMAPINFOHEADER));
    bi.biSize        = sizeof(BITMAPINFOHEADER);
    int ret = GetDIBits(m_WorkDC.m_hDC,
        (HBITMAP)m_WorkBmp.GetSafeHandle(),
        0,
        bi.biHeight,
        NULL,
        (BITMAPINFO*)&bi,
        DIB_RGB_COLORS);
    bi.biCompression = BI_RGB;

    unsigned char *bmpBuffer = new unsigned char[bi.biSizeImage];

    ret = GetDIBits(m_WorkDC.m_hDC,
             (HBITMAP)m_WorkBmp.GetSafeHandle(),
              0,
              bi.biHeight,
              (void*)bmpBuffer,
              (BITMAPINFO*)&bi,
              DIB_RGB_COLORS);

So far I have DIB in bmpBuffer, now I'd like to draw this image, but here is my confusion. I beleivbe it is already in pixel format so I use:
Code: [Select]
   sf::Image backgroundImage;
    bool b = backgroundImage.LoadFromPixels(bi.biWidth, bi.biHeight, (const unsigned char*)bmpBuffer);
    delete [] bmpBuffer;
    sf::Sprite background = sf::Sprite(backgroundImage);
    m_pSfmlView->Draw(background);


It doesnt work. I debug it littel bit and looks like this DIB is just part of bitmap without the header, so small function that I grab from SOIL fix the problem:

Code: [Select]
void CMapView::ConvertToPixels(int img_x, int img_y, unsigned char *out)
{
    int target = 4;
    int z = 0;

    for (int j=0; j < (int) img_y; ++j)
    {
        for (int i=0; i < (int) img_x; ++i)
        {
            int a;
            char ch = out[z+2];
            out[z+2] = out[z];
            //                out[z+1] = get8();
            out[z] = ch;
            z += 3;
            a = 255;
            if (target == 4) out[z++] = a;
        }
    }

    unsigned char t;
    for (int j=0; j < (int) img_y>>1; ++j)
    {
        unsigned char *p1 = out + j * img_x * target;
        unsigned char *p2 = out + (img_y-1-j)*img_x*target;
        for (int i=0; i < (int) img_x*target; ++i)
        {
            t = p1[i];
            p1[i] = p2[i];
            p2[i] = t;
        }
    }
}


It works, but I am really unhappy with the performance because one copy and 2 conversions (150-200 ms in debug mode). So in ideal case it could be something like

Code: [Select]
   m_map.Output(&m_WorkDC);
    // Init OpenGL
    sf::WindowSettings st;
    st.AntialiasingLevel = 8;  // Make smooth drawing
    m_pSfmlView = new sf::RenderWindow(m_WorkDC, st);

So it should eliminate needs to copy/convert DIB. If there are better way to do so, please help me.
Thanks
Aleksey

hippocat

  • Newbie
  • *
  • Posts: 17
    • View Profile
GetDIBits and LoadFromPixels incompatible
« Reply #1 on: March 04, 2010, 10:07:56 pm »
So , folks, what I am doing wrong here ? Or not I ;) ...