How to display a Bitmap with Gamma Correction in Autodesk 3dsmax

A customer asked me the other day how to display a Bitmap with the gamma correction. He was writing a custom maxscript UI control, and wanted to display a maxscript bitmap on the UI control. Ok, fair enough. Once he displayed the image, he found the image displayed as too dark. The same problem was found with the ImgTag maxscript UI control (found in maxsdksamplesmaxscriptmxsagniimgtag.cpp). A bitmap displayed in the ImgTag control was also displayed as too dark. This maxscript showed the problem when ran in 3dsmax 2012:

p = "E:\Dev\defects\chris_haydon_100.jpg"
b = openbitmap p
display b

rollout TOO_DARK "too dark imgtag"
(
    imgtag n "fish" bitmap:b
)
createDialog TOO_DARK width:400 height:400

What you would see is the Image on the maxscript dialog UI control would be too dark, while the image displayed in the normal maxscript bitmap would be normal.

The reason is because starting in 3dsmax 2012, gamma settings were turned on by default. In previous versions it was turned off. And the ImgTag code completely ignored gamma settings.

To display a Bitmap (maxsdkincludebitmap.h) correctly you have to pass in TRUE for the last parameter to

Bitmap::ToDib( int depth, UWORD *gam, BOOL dither, BOOL displayGamma )

This is used in code like this:

PBITMAPINFO bmi = mbm->bm->ToDib(32, NULL, FALSE, TRUE);

So for instance, the ImgTag was fixed to display a bitmap correctly with gamma in the following code:

Code Snippet
int ImgTag::SetBitmap(Value* val)
{
    if(val == &undefined)
    {
        if(m_hBitmap) DeleteObject(m_hBitmap);
        m_hBitmap = NULL;
        m_maxBitMap = NULL;
    }
    else
    {
        HWND hWnd = MAXScript_interface->GetMAXHWnd();

        MAXBitMap* mbm = (MAXBitMap*)val;
        type_check(mbm, MAXBitMap, _T("set .bitmap"));
        m_maxBitMap = val;

        HDC hDC = GetDC(hWnd);
        PBITMAPINFO bmi = mbm->bm->ToDib(32, NULL, FALSE, TRUE);
        if(m_hBitmap)
            DeleteObject(m_hBitmap);
        m_hBitmap = CreateDIBitmap(hDC, &bmi->bmiHeader, CBM_INIT, bmi->bmiColors, bmi, DIB_RGB_COLORS);
        LocalFree(bmi);
        ReleaseDC(hWnd, hDC);
    }

    Invalidate();
    return 1;
}

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s