Поиск:

Ответ в темуСоздание новой темы Создание опроса
> BMP объясните пожалуйста 
:(
    Опции темы
kurlyak
Дата 19.10.2009, 19:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

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



У меня есть кусок программы- он работатет. Суть заключаеться в том, что  этот кусок пр. выводит изображение БМП в виде региона назначенного диалогу. То есть по очертаниям БМП рисуеться диалог (нестандартный). Вот код:

Код

// TODO: Add extra initialization here
    
    maskBitmap = (HBITMAP)LoadImage(NULL, "avatar.bmp", 
                               IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
    if (!maskBitmap) return NULL;

    BITMAP bi;
    BYTE bpp;
    DWORD TransPixel;
    DWORD pixel;
    int startx;
    INT i, j;
    HRGN Rgn, ResRgn = CreateRectRgn(0, 0, 0, 0);

    GetObject(maskBitmap, sizeof( BITMAP ), &bi);

    bpp = bi.bmBitsPixel >> 3;

    BYTE *pBits = new BYTE[ bi.bmWidth * bi.bmHeight * bpp ];

    int  p = GetBitmapBits( maskBitmap, bi.bmWidth * bi.bmHeight * bpp,
                                                                pBits );

    TransPixel = *(DWORD*)pBits;

    TransPixel <<= 32 - bi.bmBitsPixel;

    for (i = 0; i < bi.bmHeight; i++)
    {
        startx=-1;
        for (j = 0; j < bi.bmWidth; j++)
        {
            pixel = *(DWORD*)(pBits + (i * bi.bmWidth +    j) * bpp) << (32 - bi.bmBitsPixel);
            if (pixel != TransPixel)
            {
                if (startx<0)
                {
                    startx = j;
                } else if (j == (bi.bmWidth - 1))
                {
                    Rgn = CreateRectRgn( startx, i, j, i + 1 );
                    CombineRgn( ResRgn, ResRgn, Rgn, RGN_OR);
                    startx=-1;
                }
            } else if (startx>=0)
            {
                Rgn = CreateRectRgn(startx, i, j, i + 1);
                CombineRgn(ResRgn, ResRgn, Rgn, RGN_OR);
                startx=-1;
            }
        }
    }
    delete pBits;
    SetWindowRgn(ResRgn, TRUE);


В частности мне не ясно почему мы сдвигаем здесь на 3 бита вправо:
bpp = bi.bmBitsPixel >> 3;

Почему мы отнимаем здесь от 32- х:
TransPixel <<= 32 - bi.bmBitsPixel;

И почему здесь отнимаем от 32- х:
pixel = *(DWORD*)(pBits + (i * bi.bmWidth +    j) * bpp) << (32 - bi.bmBitsPixel);

Что это все дает?
PM MAIL   Вверх
mes
Дата 19.10.2009, 21:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


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

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



сдвиг вправо на 3 аналогичен целочисленному делению на 8 (2 в 3й степени) - этой операции, имея кол-во бит_про_пиксел,  узнаем кол-во байт_про_пиксел.

32 это кол-во бит в DWORD.

вся эта арифметика нужна, чтоб перемещаться по памяти "по-пиксельно" .



--------------------
PM MAIL WWW   Вверх
Alexeis
Дата 19.10.2009, 21:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

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



bpp = bi.bmBitsPixel >> 3; тоже что bi.bmBitsPixel / 8; // галимая оптимизация в ненужно месте. делим биты на 8 и получаем байты. 3 байта занимает цветовая часть пикселя. 
TransPixel <<= 32 - bi.bmBitsPixel; - скорее всего получают значение альфа-канала пиксела из общего цвета. Сдвигают все байты чтобы остался только канал прозрачности.

32 - bi.bmBitsPixel = 32 - 24 = 8 бит прозрачности.
Это уже галимая универсальность, учитывая что битмап поддерживает только один формат прозрачности, да и тот не настоящий стандарт, а де факто.
Формат цвета 32 бита 24 бита цвет + 8 бит альфа-канал. Других просто нет. RGBA
8 бит красный 8 зеленый 8 синий 8 альфа.

Правильно будет просто проверить является ли формат 32х битным, если нет, то просто прекратить загружать из него, если да, то считать его как 8:8:8:8 и ничего не вычислять smile .


--------------------
Vit вечная память.

Обсуждение действий администрации форума производятся только в этом форуме

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
kurlyak
Дата 20.10.2009, 12:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

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



Большое спасибо!
У меня bi.bmBitsPixel = 32 я проверял в программе а не 24 как вы указали выше. Если например это значение как для монохромного изображения равно 4 (если я не ошибаюсь) что занчит следующее:

Код

TransPixel <<= 32 - bi.bmBitsPixel;
.......
pixel = *(DWORD*)(pBits + (i * bi.bmWidth +    j) * bpp) << (32 - bi.bmBitsPixel);


Причем TransPixel это как описано в книге цвет исходного левого крайнего пикселя. Мы сравниваем с ним все пиксели, что бы найти гранцы изображения. Почему мы именно следующий пиксель находим когда делаем <<(32 - bi.bmBitsPixel) если и так понятно что i, j строка и точка в строке умножаються (см. ниже) добавляються и еще раз умножаютсья на bpp - мы и должны получить следующий пиксель, зачем здесь << (32 - bi.bmBitsPixel):

Код

pixel = *(DWORD*)(pBits + (i * bi.bmWidth +    j) * bpp) << (32 - bi.bmBitsPixel);


И что у меня в программе значит bi.bmBitsPixel = 32 значти что rgb занимают 32 разряда? А альфа тогда как? 

Это сообщение отредактировал(а) kurlyak - 20.10.2009, 13:48
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Visual C++/MFC/WTL | Следующая тема »


 




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


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

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