Модераторы: feodorv, GremlinProg, xvr, Fixin
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> CreateDIBSection, Нужен пример юзания 
:(
    Опции темы
MoZy
Дата 21.10.2006, 18:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 193
Регистрация: 4.6.2006

Репутация: 1
Всего: 0



Привет!
Мне нужно получить растр, обработать и воткнуть обратно в ДЦ. А еще лучше изменять ДЦ напрямую, или как сказано про CreateDIBSection: function creates a device-independent bitmap (DIB) that applications can write to directly. 

И сразу вопрос: какую роль играет первый параметр в этой функции? Просто как цветовой шаблон или в lpBits будет записано содержимое DC? Если не будет, то как это сделать. Хотелось бы кусок кода как это сделать.

Для удобства приведу свой, результатом которого является серый квадрат:

Код

        hdc = GetDC(0); 
        HDC MemDC=CreateCompatibleDC(hdc);

        RECT rcClient;
        GetWindowRect(GetDesktopWindow(), &rcClient);
        int x,y,n,r,g,b,rx,ry;
        
        
        BITMAPINFOHEADER bmi = {0};
        bmi.biSize = sizeof (bmi);
        bmi.biPlanes = 1;
        bmi.biBitCount = 32;
        bmi.biWidth = 100;
        bmi.biHeight = 100;
        
        BYTE *pBGro = new BYTE[100*100*4];

        HBITMAP bitmp = CreateDIBSection(hdc,(BITMAPINFO*)&bmi,DIB_RGB_COLORS,(void**)pBGro,NULL,NULL);
        SelectObject(MemDC,bitmp);
        BitBlt(MemDC,0,0,rcClient.right,rcClient.bottom,hdc,0,0,SRCCOPY);

        SetDIBitsToDevice(MemDC,0,0, 1152, 768,0,0,0,768,pBGro,(BITMAPINFO*) &bmi,DIB_RGB_COLORS);
        BitBlt(hdc,0,0,rcClient.right,rcClient.bottom,MemDC,0,0,SRCCOPY);
        ReleaseDC(hwnd, hdc);


В данном случае я пытаюсь создать секцию, записать в нее с экрана, потом из нее вывести на экран
--------------------
Experimentia est optima rerum magistra
PM MAIL WWW ICQ   Вверх
Earnest
Дата 23.10.2006, 13:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5962
Регистрация: 17.6.2005
Где: Рязань

Репутация: 33
Всего: 183



Кажется, ты некорректно заполняешь структуру BITMAPINFO. Вот рабочий пример создания (это класс, оборачивающий DibSection).
Код

BOOL CDibSection::Create (HDC hDC,UINT nWidth,UINT nHeight,WORD nBitCnt,LPRGBQUAD pColors) {

    // создаем "упакованную" структуру BITMAPINFO
    int  nCols=1<<nBitCnt;
    UINT nSize=sizeof(BITMAPINFOHEADER);
    if (nBitCnt <= 8) 
        nSize+=+nCols*sizeof(RGBQUAD);
    
    m_pBmi=(LPBITMAPINFO) new char [nSize];
    if (!m_pBmi) return FALSE;

    // заполняем ее ...
    m_pBmih=&m_pBmi->bmiHeader;
    m_pColors=(nBitCnt <= 8)?m_pBmi->bmiColors:NULL;
    memset (m_pBmih,0,sizeof(BITMAPINFOHEADER));
    
    m_pBmih->biSize         =sizeof(BITMAPINFOHEADER);
    m_pBmih->biWidth         =nWidth; 
    m_pBmih->biHeight         =nHeight; 
    m_pBmih->biPlanes         =1; 
    m_pBmih->biBitCount     =nBitCnt; 
    m_pBmih->biCompression=BI_RGB; 
    m_pBmih->biClrUsed     =(nBitCnt <= 8)?nCols:0;
    m_pBmih->biXPelsPerMeter=m_pBmih->biYPelsPerMeter=Round(300/0.024);

    DWORD nUseColors=DIB_RGB_COLORS;
    if (pColors && m_pColors) {
        // копируем переданную таблицу цветов - считаем ее полной
        memcpy (m_pColors,pColors,nCols*sizeof(RGBQUAD));
    }
    else if (nBitCnt==1) {
        memset (m_pColors,0,sizeof(RGBQUAD)*2);
        m_pColors[1].rgbRed=m_pColors[1].rgbGreen=m_pColors[1].rgbBlue=255;
    }
    else if (nBitCnt <= 8) {    
        // заполняем таблицу цветов прямыми ссылками на системную таблицу
        LPWORD pIndex=(LPWORD)m_pColors;
        for (int i=0; i < nCols; i++) *pIndex++=i;
        nUseColors=DIB_PAL_COLORS;
    }

    m_hBitmap=CreateDIBSection (hDC,m_pBmi,nUseColors,(LPVOID*)&m_pBits,NULL,NULL);
    if (!m_hBitmap) return FALSE;

    m_nBpline=BytesPerLine (m_pBmih->biWidth,m_pBmih->biBitCount);
    return TRUE;
}



--------------------
...
PM   Вверх
MoZy
Дата 23.10.2006, 20:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 193
Регистрация: 4.6.2006

Репутация: 1
Всего: 0



Earnest, ой не знаю. Правильно неправильно, а я все равно не понял. Зачем нужен этот растр, если все равно изменяется только он. А чтобы увидеть изменения все равно надо SetDIBToDevice.

Earnest, а в твоем примере я смогу в секцию че-нить записать с помощью BitBlt? А то смысл теряется, если нет.
--------------------
Experimentia est optima rerum magistra
PM MAIL WWW ICQ   Вверх
Earnest
Дата 24.10.2006, 08:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5962
Регистрация: 17.6.2005
Где: Рязань

Репутация: 33
Всего: 183



Не надо SetDIBToDevice. Все, что ты меняешь в дибе (т.е. в блоке pBits) - это и есть изменения соответствующего мемори-контекста. Другое дело, чтобы это увидеть, нужно содержимое мемори контекста бросить на экранный контекст. Для этого достаточно BitBlt, и это достаточно быстрая операция.

В DIB-секцию можно писать и через мемори-контекст, в котором она выбрана как подложка (BitBlt или любые графические операции - рисование линий, вывод текста, etc), и прямо (биты менять). В том-то и смысл ее.


--------------------
...
PM   Вверх
MoZy
Дата 27.10.2006, 18:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 193
Регистрация: 4.6.2006

Репутация: 1
Всего: 0



Earnest, круто, спасибо! я на это и надеялся. да вот только скажи, пожалуйста, тот hdc, который как параметр в функцию идет - это и есть тот самый, который тесно связан с растром, или нужно как-то потом SelectObject'ом выбирать ту битмапу, которая возвращается функцией?  smile 
--------------------
Experimentia est optima rerum magistra
PM MAIL WWW ICQ   Вверх
Earnest
Дата 30.10.2006, 11:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5962
Регистрация: 17.6.2005
Где: Рязань

Репутация: 33
Всего: 183



Смотря в какую функцию.
Если для создания DIBSection - то любой сойдет, хоть десктопа.
А если для рисования в растр, то, конечно, это должен быть тот самый "compatible dc", созданный по любому экранному dc и в котором выбрана DibSection. А как же иначе?


--------------------
...
PM   Вверх
MoZy
Дата 30.10.2006, 20:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 193
Регистрация: 4.6.2006

Репутация: 1
Всего: 0



Мдааа. Странно. 
Earnest, с помощью твоей замечательной функции наконец-то создается у меня DIBSection. Правда сколько я не пытался писать в растр, на контексте это никак не отображается. Впрочем как и наоборот ) И еще почему-то когда я выбираю 32 битную палитру, растр вдруг становится двойного размера, то есть на один пиксель уходит 8 байт!
Я немного подсократил функцию (может в этом проблема, но я просто не знаю откуда взять RGBQUAD):
Код

int CreateSection (HDC hDC,BYTE *m_pBits, UINT nWidth,UINT nHeight,WORD nBitCnt) {

    // создаем "упакованную" структуру BITMAPINFO
    int  nCols=1<<nBitCnt;
    UINT nSize=sizeof(BITMAPINFOHEADER);
    if (nBitCnt <= 8) 
        nSize+=+nCols*sizeof(RGBQUAD);
    
    BITMAPINFO *m_pBmi=(LPBITMAPINFO) new char [nSize];
    if (!m_pBmi) return FALSE;

    // заполняем ее ...
    BITMAPINFOHEADER *m_pBmih=&m_pBmi->bmiHeader;
    LPRGBQUAD m_pColors=(nBitCnt <= 8)?m_pBmi->bmiColors:NULL;
    memset (m_pBmih,0,sizeof(BITMAPINFOHEADER));
    
    m_pBmih->biSize         =sizeof(BITMAPINFOHEADER);
    m_pBmih->biWidth         =nWidth; 
    m_pBmih->biHeight         =nHeight; 
    m_pBmih->biPlanes         =1; 
    m_pBmih->biBitCount     =nBitCnt; 
    m_pBmih->biCompression=BI_RGB; 
    m_pBmih->biClrUsed     =(nBitCnt <= 8)?nCols:0;
    m_pBmih->biXPelsPerMeter=m_pBmih->biYPelsPerMeter=(int)(300/0.024);

    DWORD nUseColors=DIB_RGB_COLORS;
    /*if (pColors && m_pColors) {
        // копируем переданную таблицу цветов - считаем ее полной
        //memcpy (m_pColors,pColors,nCols*sizeof(RGBQUAD));
    }*/
    if (nBitCnt==1) {
        memset (m_pColors,0,sizeof(RGBQUAD)*2);
        m_pColors[1].rgbRed=m_pColors[1].rgbGreen=m_pColors[1].rgbBlue=255;
    }
    else if (nBitCnt <= 8) {    
        // заполняем таблицу цветов прямыми ссылками на системную таблицу
        LPWORD pIndex=(LPWORD)m_pColors;
        for (int i=0; i < nCols; i++) *pIndex++=i;
        nUseColors=DIB_PAL_COLORS;
    }
    
    hBitmap=CreateDIBSection (hDC,m_pBmi,nUseColors,(LPVOID*)&m_pBits,NULL,NULL);
    if (!hBitmap) return FALSE;

    return TRUE;
}

У тебя случайно нет примерчика использования уже созданной DIBSection, а конкретнее работы с растром?
я так пытаюсь:
Код

#define RBIT(pix) BYTE(pix>>16)
#define GBIT(pix) BYTE(pix>>8)
#define BBIT(pix) BYTE(pix)
#define MAKERGB(r,g,b,a) ( (a<<24)|(r<<16)|(g<<8)|b )
#define MAPBIT(pBits,w,x,y)   (*(DWORD*)(pBits + (y * w + x) * 4))

BYTE *pBGro = new BYTE[500*500*4];

hdc = GetDC(0);

MemDC=CreateCompatibleDC(hdc);
CreateSection (MemDC,pBGro, 500,500,32);
SelectObject(MemDC,hBitmap); 

case WM_TIMER:
hdc = GetDC(0);

StretchBlt(MemDC,0,0,500,500,hdc,-25+15*sin(j*0.05),-20+15*cos(j*0.5),550,550,SRCCOPY);
j++;
if(j>=360*20)j=0;
        
        int i;
        for(y=0;y<500;y++)
        {
            for(x=0;x<500;x++)
            {
                pix=MAPBIT(pBGro,500,x,y); 
                r=RBIT(pix);
                g=GBIT(pix);
                b=BBIT(pix);
                SetBit(pBGro,500,x,y,MAKERGB(0,g,0,0));
            }
        }

BitBlt(hdc,0,0,500,500,MemDC,0,0,SRCCOPY);
ReleaseDC(hwnd, hdc);

return 0;

и в итоге действия над растром вообще не воспринимаются  smile 
--------------------
Experimentia est optima rerum magistra
PM MAIL WWW ICQ   Вверх
Earnest
Дата 31.10.2006, 08:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5962
Регистрация: 17.6.2005
Где: Рязань

Репутация: 33
Всего: 183



Я не понимаю тах сходу, что ты пытаешься засунуть в растр. А разбираться, извини, лень. Очевидно одно: за один раз нужно решать одну задачу, иначе ничего не получится. Я имею в виду, что у тебя слишком много мест, где может быть ошибка:
1) создание диб-секции (кстати, у меня был класс, а ты что, переменные гобальными сделал?) и выбор ее в контекст
2) StrechBlt в мемори-контекст
3) изменение битов диба
3) BitBlt на экран (ты ведь сразу пытаешься писать в контекст десктопа...).
Каждый из этих пунктов нуждается в отдельной проверке. А сама последовательность вполне правильная: создаем секцию, выбираем в контекст, копируем что-то из другого контекста, дорисовываем прямой записью, копируем обратно...

Правильно ли создается диб-секция? Заполни биты чем-нибудь, ну хоть красным или синим и выведи в обычное окно, с простыми координатами. Кстати, формат пикселов в дибе вовсе не RGB - в 24-битовом случае байты идут наоборот, а в 32 - не помню, но как-то с масками связано, а не так как ты думаешь, судя по коду.
Кроме того, размер строки диба должен быть выровнен на двойное слово...

Для проверки после выбора в контекст спроси у него параметры выбранного битмапа.

Работай пока со своим окном и русуй на OnPaint.
Прямую запись в растр пробуй на чем-нибуть простом, что легко проверить, заглянув в память: полоски нарисуй, например.

И так по каждому пункту.

Добавлено @ 08:49 
Вот еще что заметила:
Где ты увидел в моей функции выделение памяти под биты?
Память под биты выделяет сама Windows, а не ты! Ты передаешь адрес указателя, который функция инициализирует. Ты хоть прочти внимательно описание CreateDibSection, чтобы понимать что к чему.



--------------------
...
PM   Вверх
MoZy
Дата 31.10.2006, 20:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 193
Регистрация: 4.6.2006

Репутация: 1
Всего: 0



Earnest, ) понять-то - понять, а выделение - дело вынужденное. Просто Винде не нравится (0хС00000005) что я пытаюсь читать из растра макросом MAPBIT. типа обращаюсь в невыделенную память, т е винда не выделяет память. вывод
Цитата

Правильно ли создается диб-секция?

нет.

Цитата

(HDC hDC,UINT nWidth,UINT nHeight,WORD nBitCnt,LPRGBQUAD pColors) {

как мне заполнить pColors?
--------------------
Experimentia est optima rerum magistra
PM MAIL WWW ICQ   Вверх
Earnest
Дата 1.11.2006, 09:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5962
Регистрация: 17.6.2005
Где: Рязань

Репутация: 33
Всего: 183



Ты пытаешься читать по невалидному адресу, конечно, программа будет падать!
Добавление к моему предыдущему посту прочти внимательно! Пока это не починишь, дальше и соваться нечего.
А pColors тебе не нужно, если у тебя растр полноцветный, здесь все правильно.


--------------------
...
PM   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Системное программирование и WinAPI"
Fixin
GremlinProg
xvr
feodorv
  • Большое количество информации и примеров с использованием функций WinAPI можно найти в MSDN
  • Описание сообщений, уведомлений и примеров с использованием компонент WinAPI (BUTTON, EDIT, STATIC, и т.п.), можно найти в MSDN Control Library
  • Непосредственно, перед созданием новой темы, проверьте заголовок и удостоверьтесь, что он отражает суть обсуждения.
  • После заполнения поля "Название темы", обратите внимание на наличие и содержание панели "А здесь смотрели?", возможно Ваш вопрос уже был решен.
  • Приводите часть кода, в которой предположительно находится проблема или ошибка.
  • Если указываете код, пользуйтесь тегами [code][/code], или их кнопочными аналогами.
  • Если вопрос решен, воспользуйтесь соответствующей ссылкой, расположенной напротив названия темы.
  • Один топик - один вопрос!
  • Перед тем как создать тему - прочтите это .

На данный раздел распространяются Правила форума и Правила раздела С++:Общие вопросы .


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Chipset, Step, Fixin, GremlinProg, xvr. feodorv.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Системное программирование и WinAPI | Следующая тема »


 




[ Время генерации скрипта: 0.1463 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.