Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Visual C++/MFC/WTL > CreateCompatibleDC grayscale


Автор: nikkadim 7.8.2012, 16:26
Добрый день,

Подскажите плз, что делаю не так - хочу выводить на экран grayscale изображение, но как только раскоментирую цикл LUT  сразу получаю вылет приложения.
Как-будто обращаюсь в невыделенную память?!


Код


    unsigned char* ptr;
    ptr = (unsigned char*)malloc( 300 * 300);
    BITMAPINFO bmi;
    ZeroMemory(&bmi, sizeof(BITMAPINFO));
    bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
    bmi.bmiHeader.biBitCount = 8;
    bmi.bmiHeader.biClrUsed = 0;
    bmi.bmiHeader.biHeight = 300;
    bmi.bmiHeader.biWidth = 300;
    bmi.bmiHeader.biSizeImage = 300*300;
    bmi.bmiHeader.biPlanes = 1;
    bmi.bmiHeader.biCompression = BI_RGB;
    //ZeroMemory(bmi.bmiColors, sizeof(RGBQUAD));
    /*
    for(int i=0; i<256; i++)
    {
        bmi.bmiColors[i].rgbRed = i;
        bmi.bmiColors[i].rgbGreen = i;
        bmi.bmiColors[i].rgbBlue = i;
        bmi.bmiColors[i].rgbReserved = 0;
    }    
    */
    HDC dc = CreateCompatibleDC((HDC)mPictureBox.GetDC());
    HBITMAP hbitmap = CreateDIBSection(dc, &bmi, DIB_RGB_COLORS, (void**)&ptr,  NULL, 0);
    
    for (int i=0; i<300*300; i++)
        ptr[i] = rand()%255;
    
    SetDIBits(dc, hbitmap, 0, 300, ptr, &bmi, DIB_RGB_COLORS );
    
    mPictureBox.SetBitmap(hbitmap);
    //mPictureBox.RedrawWindow();
//free(ptr)


Добавлено через 7 минут и 10 секунд
не понял почему, но обошел вот так:
Код

    unsigned char* ptr;
    ptr = (unsigned char*)malloc( 300 * 300);



    BITMAPINFO bmi;
    LPBITMAPINFO info; 
    info = (LPBITMAPINFO) malloc(sizeof(BITMAPINFO) + 256 * sizeof(RGBQUAD));
    //ZeroMemory(&bmi, sizeof(BITMAPINFO) + 256 * sizeof(RGBQUAD));
    info->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
    info->bmiHeader.biBitCount = 8;
    info->bmiHeader.biClrUsed = 0;
    info->bmiHeader.biHeight = 300;
    info->bmiHeader.biWidth = 300;
    info->bmiHeader.biSizeImage = 300*300;
    info->bmiHeader.biPlanes = 1;
    info->bmiHeader.biCompression = BI_RGB;
    //ZeroMemory(bmi.bmiColors, sizeof(RGBQUAD));
    
    for(int i=0; i<256; i++)
    {
        info->bmiColors[i].rgbRed = i;
        info->bmiColors[i].rgbGreen = i;
        info->bmiColors[i].rgbBlue = i;
        info->bmiColors[i].rgbReserved = 0;
    }    
    
    HDC dc = CreateCompatibleDC((HDC)mPictureBox.GetDC());
    HBITMAP hbitmap = CreateDIBSection(dc, info, DIB_RGB_COLORS, (void**)&ptr,  NULL, 0);
    
    for (int i=0; i<300*300; i++)
        ptr[i] = rand()%255;
    
    SetDIBits(dc, hbitmap, 0, 300, ptr, info, DIB_RGB_COLORS );
    
    mPictureBox.SetBitmap(hbitmap);
    //mPictureBox.RedrawWindow();

    //free (ptr);

Автор: korian 7.8.2012, 17:22
Цитата(nikkadim @  7.8.2012,  15:26 Найти цитируемый пост)
не понял почему, но обошел вот так:

Код

typedef struct tagBITMAPINFO {
  BITMAPINFOHEADER bmiHeader;
  RGBQUAD          bmiColors[1]; // <<<<<<< Потому что
} BITMAPINFO, *PBITMAPINFO;

Автор: nikkadim 7.8.2012, 17:24
Спасибо!
Туда заглянуть не хватило мозгов.

Автор: nikkadim 8.8.2012, 21:04
Цитата(korian @ 7.8.2012,  17:22)
Цитата(nikkadim @  7.8.2012,  15:26 Найти цитируемый пост)
не понял почему, но обошел вот так:

Код

typedef struct tagBITMAPINFO {
  BITMAPINFOHEADER bmiHeader;
  RGBQUAD          bmiColors[1]; // <<<<<<< Потому что
} BITMAPINFO, *PBITMAPINFO;

Означает ли это, что для 16-bit ного изображения надо делать вот так?

Код

    for(int i=0; i<65536; i++)
    {
        info->bmiColors[i].rgbRed = i;
        info->bmiColors[i].rgbGreen = i;
        info->bmiColors[i].rgbBlue = i;
        info->bmiColors[i].rgbReserved = 0;
    }  


Правильно ли я понимаю, что вывести на экран 16-bit grayscale изображение в принципе не возможно, ни под виндой ни под чем  - да?

PS: http://www.qtcentre.org/threads/15518-How-to-display-16-bit-grayscale-pictures?p=79032#post79032
PPS: http://forums.codeguru.com/archive/index.php/t-374992.html

Автор: Earnest 9.8.2012, 06:34
Цитата(nikkadim @  8.8.2012,  22:04 Найти цитируемый пост)
Означает ли это, что для 16-bit ного изображения надо делать вот так?

Нет, конечно; 16-битное изображение рассматривается как полноцветное, не как палитровое

Цитата(nikkadim @  8.8.2012,  22:04 Найти цитируемый пост)
Правильно ли я понимаю, что вывести на экран 16-bit grayscale изображение в принципе не возможно, ни под виндой ни под чем  - да?

Насчет "ни под чем" не знаю, а под виндой не получится.
С другой стороны - оно надо? Человек-то и 256 градаций серого едва различает... 

Винде надо  дать распределение битов по каналом - битовую маску той части пиксела, которая отвечает за канал.
Но поскольку рисовать как-то надо, и желательно без доп. преобразований, мы выкручивались так:
битовые маски, оказывается, вполне могут накладываться и даже совпадать. Т.о.  в каждый канал поступает одинаковое значение, в результате - серый цвет. Не 64 тысячи градаций, но посмотреть хватает.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)