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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> GetDIBits - получить растр, GDI 
V
    Опции темы
Annuta
Дата 22.2.2007, 13:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

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



Привет... У меня прога выводит гифовские анимашки на экранчик через USB порт. Беру и в цикле раскладываю каждый кадр в массив RGB и уже этот массив передаю в порт. 
 Раньше пользовалась GetPixel(); Но уж оочень она медленная - хочу переделать это 
на GetDIBits ... нашла код ... переписала ... и ошибок не выдаёт - но и в массиве pBits
ничего нет !!! Хотя там по моему разумению должен быть растр картинки т.е. RGB сост каждого бита... привожу код Помогите плиз ... 
Код

//Вывожу в цикле кадры анимашки
while (!m_bExitThread)
    {        
             HDC hMemDC = NULL;
        HBITMAP hMemBM = NULL, hOldBM = NULL;

        if (m_arrFrames[nTemp].m_pPicture) //Кадр
        {            
            if (m_arrFrames[nTemp].m_nDisposal == 3)
            {
                // prepare a memory DC and store the background in it
                hMemDC = CreateCompatibleDC(m_hMemDC);
                hMemBM = CreateCompatibleBitmap(m_hMemDC,
                            m_arrFrames[nTemp].m_frameSize.cx,
                            m_arrFrames[nTemp].m_frameSize.cy);
                
            if (hMemDC && hMemBM)
            {
               hOldBM = reinterpret_cast<HBITMAP> (SelectObject(hMemDC,hMemBM));
            };
        };
        

        long hmWidth;
        long hmHeight;
        
                   m_arrFrames[nTemp].m_pPicture->get_Width(&hmWidth);
            m_arrFrames[nTemp].m_pPicture->get_Height(&hmHeight);

            if (m_arrFrames[nTemp].m_pPicture->Render(m_hMemDC, 
                m_arrFrames[nTemp].m_frameOffset.cx, 
                m_arrFrames[nTemp].m_frameOffset.cy, 
                m_arrFrames[nTemp].m_frameSize.cx, 
                m_arrFrames[nTemp].m_frameSize.cy, 
                0, hmHeight, hmWidth, -hmHeight, NULL) == S_OK)
            {
                Invalidate(FALSE);
                
                //HBITMAP hOldBM = NULL;

            HDC bDC = CreateCompatibleDC(0);  //создаем DC для нашего битмапа
              SelectObject(bDC, hOldBM);                 //Назначаем DC для нашего битмапа

            tagBITMAP bmInfo;                            

            GetObject(hOldBM, sizeof(bmInfo), &bmInfo); //Получаем инфу о DDB

BITMAPINFO DIBInfo;
  memset(&DIBInfo, 0, sizeof(DIBInfo)); //Готовим структуру для создания DIB.

  DIBInfo.bmiHeader.biWidth         = 132;
  DIBInfo.bmiHeader.biHeight        = 132;
  DIBInfo.bmiHeader.biPlanes        = 1;      // всегда 1
  DIBInfo.bmiHeader.biCompression   = BI_RGB; // без компрессии
  DIBInfo.bmiHeader.biBitCount      = 24;     // три байта на пиксель
  DIBInfo.bmiHeader.biSize          = sizeof(DIBInfo.bmiHeader);
  DIBInfo.bmiHeader.biXPelsPerMeter = 2834;   // пикселей на метр, гор.    
  DIBInfo.bmiHeader.biYPelsPerMeter = 2834;   // пикселей на метр, верт. 

BYTE* pBits  = NULL;     //тут будет растр DIB 
HBITMAP dib  = NULL;    //Хендл DIB вдруг понадобится :)

 
//Создаем пустой DIB в памяти на основе установленых параметров.
//dib = CreateDIBSection(bDC, &DIBInfo, DIB_RGB_COLORS, (VOID**)&pBits, 0, 0);

//Конвертируем DDB в DIB указанного формата.
  GetDIBits(m_hMemDC, hOldBM, 0, 131, pBits, &DIBInfo, DIB_RGB_COLORS);

  DIBInfo.bmiHeader.biBitCount = BI_BITFIELDS ;
  DWORD * pBitFields = (DWORD *) DIBInfo.bmiColors;
        DWORD red   = pBitFields[0];
        DWORD green = pBitFields[1];
        DWORD blue  = pBitFields[2];

  

//Усе теперь функция GetDIBits, по адресу pBits записала растр. 
//Это оставила для сравнения цветов на пока ... 
                    
            rgb arr[132][132]; 
            
                for (int i = 0; i < 132; i++) 
                {     
                    for (int j = 0; j < 132; j++) 
                    { 
                        COLORREF cr = GetPixel(m_hMemDC,i,j); 
                        arr[i][j].r = GetRValue(cr); 
                        arr[i][j].g = GetGValue(cr); 
                        arr[i][j].b = GetBValue(cr); //Это конечный массив
                    }
                    
                }

///////////////////////////////////////////////////////

--------------------
Программист - это комбинация лени и логики !
PM MAIL   Вверх
MoZy
Дата 22.2.2007, 21:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

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



Попробуй так. Оброти внимание на выделенный текст 

BITMAPINFOHEADER bmi = {0};
bmi.biSize = sizeof (BITMAPINFOHEADER); 
bmi.biWidth = YARD_W*2;
bmi.biHeight = YARD_W/2;
bmi.biPlanes = 1; 
bmi.biBitCount = 1;
BYTE *lpBits;
CreateDIBSection(hdc,(BITMAPINFO*)&bmi,DIB_RGB_COLORS,(void**)&lpBits,NULL,0);
--------------------
Experimentia est optima rerum magistra
PM MAIL WWW ICQ   Вверх
akahan
Дата 24.2.2007, 02:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Вот мой код, который работает! Функция GrayBitmap получает битмап, который обесцвечивает и возвращает обратно.
По аналогии можете найти ошибку в вашем коде или спользовать мой для ваших целей!
Код

void GrayBuffer( const char * pBuffer, int pLen)
{
    int res = 0;
    const double rMask = 0.212671;
    const double gMask = 0.715160;
    const double bMask = 0.002169;

    __asm
    {
        mov eax, pBuffer
        mov ecx, pLen
        sub ecx, 4
        fninit
        xor ebx, ebx
_lp:
        mov bl, byte ptr [eax][ecx]
        mov res, ebx
        fild [res]
        fmul [rMask]

        mov bl, byte ptr [eax][ecx+1]
        mov res, ebx
        fild [res]
        fmul [gMask]
        fadd

        mov bl, byte ptr [eax][ecx+2]
        mov res, ebx
        fild [res]
        fmul [bMask]
        fadd
        fistp [res]

        mov ebx, res
        mov byte ptr [eax][ecx+2], bl
        mov byte ptr [eax][ecx+1], bl
        mov byte ptr [eax][ecx], bl

        sub ecx, 4
        or    ecx, ecx
        jnz _lp
    }
}

HBITMAP GrayBitmap(HWND hWnd, HBITMAP hSource)
{
    BITMAP hBmp;
    if(GetObject(hSource, sizeof(BITMAP), &hBmp))
    {
        LPBITMAPINFO bBmi;
        if(bBmi = (LPBITMAPINFO)GlobalAlloc(GPTR, sizeof(BITMAPINFOHEADER) + ( hBmp.bmWidth * hBmp.bmHeight * sizeof(RGBQUAD))))
        {
            HBITMAP hDest;
            bBmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
            HDC dc = GetDC(NULL);
            GetDIBits( dc, hSource, 0, hBmp.bmHeight, NULL, bBmi, DIB_RGB_COLORS); // получаем инфу о битмапе в bBmi
            int bufSize = bBmi->bmiHeader.biSizeImage;
            int result = 0;
            char * buffer;
            if(buffer = (char *)GlobalAlloc(GPTR, bufSize))
            {
                if(GetDIBits(dc, hSource, 0, hBmp.bmHeight, (LPVOID)buffer, bBmi, DIB_RGB_COLORS)) // а вот здесь получаем в buffer наши пиксели :)
                {
                    GrayBuffer(buffer, bufSize);
                    hDest = CreateCompatibleBitmap(dc, hBmp.bmWidth, hBmp.bmHeight );
                    result = SetDIBits(dc, hDest, 0, hBmp.bmHeight, (LPVOID)buffer, bBmi, DIB_RGB_COLORS);
                }
                GlobalFree(buffer);
            }
            GlobalFree(bBmi);
            if(result) return hDest;
        }
    }
    return NULL;
}



Если сделаете по аналогии, то ваш код будет работать гораздо быстрее GetPixel smile

Это сообщение отредактировал(а) akahan - 24.2.2007, 02:40
PM MAIL   Вверх
MoZy
Дата 24.2.2007, 19:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

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



akahan, да уж. GetPixel - это тормаз GDI. Слушай, а тебе не нада к твоему коду еще код смешения цвета, чтоб самому прозрачность делать? Если картинка маленькая или не в реалтайме, то можно сделать с автоматическим антиалиасингом (если рисуешь например в Фотошопе). Все картинки так же будут с полупрозрачными краями.
--------------------
Experimentia est optima rerum magistra
PM MAIL WWW ICQ   Вверх
akahan
Дата 24.2.2007, 19:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



MoZy, нет не надо тут ничего добавлять! Какой будет исходный битмап, такой будет и обесцвеченная копия. Если будет с альфа-каналом, то он не изменится! smile
PM MAIL   Вверх
GremlinProg
Дата 24.2.2007, 23:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2706
Регистрация: 9.8.2005
Где: Тюмень

Репутация: 99
Всего: 106



Annuta, дибы не совместимы с девайсом 0. Поэтому в CreateCompatibleDC необходимо передавать девайс экрана. И еще один момент. При использовании 24 битного растра, Каждая строка должна быть выровнена на границе двойного слова. Если хочешь идти по простому пути, то установи 32 бита, тогда  pBits будет точно указывать на массив RGBQUAD, который не нужно выравнивать.


--------------------
"Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины."
PM WWW ICQ   Вверх
akahan
Дата 25.2.2007, 09:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Annuta, вы бы хоть в курсе нас держали, как идет написание кода? smile
Люблю девушек-кодеров! smile

Это сообщение отредактировал(а) akahan - 25.2.2007, 09:10
PM MAIL   Вверх
Annuta
Дата 26.2.2007, 09:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

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



Привет народ.. спасибо за наставление - у меня 16 битовый растр - с этим проблем нет... У меня всё получилось Спасибо
akahan... 
а вот переложить биты RGB правильно не получается... краски плывут...
Самое интресное что на одних гифах плывут а на других нет !!! просто мистика какя-то !!!
а это моя структура...
Код

  DIBInfo.bmiHeader.biWidth         = bmInfo.bmWidth;
  DIBInfo.bmiHeader.biHeight        = bmInfo.bmHeight;
  DIBInfo.bmiHeader.biPlanes        = 1;      // всегда 1
  DIBInfo.bmiHeader.biCompression   = BI_RGB; // без компрессии
  DIBInfo.bmiHeader.biBitCount      = 24;     // три байта на пиксель
  DIBInfo.bmiHeader.biSize          = sizeof(DIBInfo.bmiHeader);
  DIBInfo.bmiHeader.biXPelsPerMeter = 2834;   // пикселей на метр, гор.    
  DIBInfo.bmiHeader.biYPelsPerMeter = 2834;   // пикселей на метр, верт. 

А так я вызываю функцию...
Код

GetDIBits(m_hMemDC, bmp, 0, bmInfo.bmHeight - 1, pBits, &DIBInfo, DIB_RGB_COLORS);

... Может кто с такой проблемой знаком ??? Присоединённый файл отображается неправильно... к сожелению не могу поместить сразу два файла... чтобы и тот выложить который правильно работает... 

Это сообщение отредактировал(а) Annuta - 27.2.2007, 12:18

Присоединённый файл ( Кол-во скачиваний: 15 )
Присоединённый файл  36_2_19_prev.gif 10,07 Kb
--------------------
Программист - это комбинация лени и логики !
PM MAIL   Вверх
zkv
Дата 28.2.2007, 04:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата



****


Профиль
Группа: Участник Клуба
Сообщений: 2133
Регистрация: 23.7.2006
Где: Санкт-Петербург

Репутация: 12
Всего: 92



Annuta, вам GremlinProg, уже рассказал про выравнивание по DWORD, отсюда и мистика, в одном случае ширина картинки кратна 4 == sizeof(DWORD) и все правильно смотрится, в другом случае получаете проблемы с выравниванием и все плывет. 

PS картинку вашу форум не дает посмотреть  smile  

Это сообщение отредактировал(а) zkv - 28.2.2007, 05:01
PM MAIL   Вверх
Earnest
Дата 28.2.2007, 16:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Annuta, действительно, у DIB и зависимого битмапа разное выравнивание: на 4 и на 2 байта соответственно. Поэтому длины строк в общем случае не совпадают. За этим нужно следить при перекладывании информации туда-сюда..


--------------------
...
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.

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


 




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


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

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