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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Создание прозрачной иконки 
:(
    Опции темы
suxxor
Дата 18.3.2012, 21:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Нужно создать иконку (HICON) и отобразить её в трее.

Значок получаю так: (взято отсюда)
Код

HICON CreateAlphaIcon(void)
{
    DWORD dwWidth = 32, dwHeight = 32;
    BITMAPV5HEADER bi;
    void *lpBits;

    ZeroMemory(&bi,sizeof(BITMAPV5HEADER));
    
    bi.bV5Size           = sizeof(BITMAPV5HEADER);
    bi.bV5Width           = dwWidth;
    bi.bV5Height          = dwHeight;
    bi.bV5Planes = 1;
    bi.bV5BitCount = 32;
    bi.bV5Compression = BI_BITFIELDS;
    // The following mask specification specifies a supported 32 BPP
    // alpha format for Windows XP.
    bi.bV5RedMask   =  0x00FF0000;
    bi.bV5GreenMask =  0x0000FF00;
    bi.bV5BlueMask  =  0x000000FF;
    bi.bV5AlphaMask =  0xFF000000; 

    HDC hdc = GetDC(NULL);

    // Create the DIB section with an alpha channel.
    HBITMAP hBitmap = CreateDIBSection(hdc, (BITMAPINFO *)&bi, DIB_RGB_COLORS, 
        (void **)&lpBits, NULL, (DWORD)0);

    HDC hMemDC = CreateCompatibleDC(hdc);
    ReleaseDC(NULL,hdc);

    // Draw something on the DIB section.
    HBITMAP hOldBitmap = (HBITMAP)SelectObject(hMemDC, hBitmap);
    PatBlt(hMemDC,0,0,dwWidth,dwHeight,WHITENESS);
    SetTextColor(hMemDC,RGB(0,0,0));
    SetBkMode(hMemDC,TRANSPARENT);
    TextOut(hMemDC,0,9,"rgba",4);
    SelectObject(hMemDC, hOldBitmap);
    DeleteDC(hMemDC);

    // Create an empty mask bitmap.
    HBITMAP hMonoBitmap = CreateBitmap(dwWidth,dwHeight,1,1,NULL);

    // Set the alpha values for each pixel in the cursor so that
    // the complete cursor is semi-transparent.
    DWORD *lpdwPixel;
    lpdwPixel = (DWORD *)lpBits;
    for (DWORD x=0;x<dwWidth;x++)
       for (DWORD y=0;y<dwHeight;y++)
       {
           // Clear the alpha bits
           *lpdwPixel &= 0x00FFFFFF;
           // Set the alpha bits to 0x9F (semi-transparent)
           *lpdwPixel |= 0x9F000000;
           lpdwPixel++;
       }

    ICONINFO ii;
    ii.fIcon = TRUE;  // Change fIcon to TRUE to create an alpha icon
    ii.xHotspot = 0;
    ii.yHotspot = 0;
    ii.hbmMask = hMonoBitmap;
    ii.hbmColor = hBitmap;

    // Create the alpha icon with the alpha DIB section.
    HICON hAlphaIcon = CreateIconIndirect(&ii);

    DeleteObject(hBitmap);          
    DeleteObject(hMonoBitmap); 

    return hAlphaIcon;
}


на выходе получается иконка с серым фоном  и чёрным текстом, в чём проблема?

Это сообщение отредактировал(а) suxxor - 18.3.2012, 21:30
PM   Вверх
GremlinProg
Дата 19.3.2012, 08:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Цитата(suxxor @  18.3.2012,  23:29 Найти цитируемый пост)
на выходе получается иконка с серым фоном  и чёрным текстом, в чём проблема?

ну а какой по твоему должен быть?

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

Добавлено через 8 минут и 59 секунд
Цитата(GremlinProg @  19.3.2012,  10:58 Найти цитируемый пост)
если иконку на черный накладывать

или на белый, смотря какой фон нарисован в иконке,
по идее - WHITENESS, т.е. белый независимо от выбранной кисти,
значит прозрачность его с 0x9F даст серый или грязный на любой темный цвет


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


Шустрый
*


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

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



неважно какой цвет текста, интересует именно: что изменить в приведённой функции для получения прозрачного фона?
PM   Вверх
GremlinProg
Дата 20.3.2012, 07:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Цитата(suxxor @  19.3.2012,  22:40 Найти цитируемый пост)
что изменить в приведённой функции для получения прозрачного фона?

если коротко, то альфу
 
здесь это 9F в 53 строке, поставишь FF, будет полностью прозрачный,
только он будет и правда полностью прозрачный, т.е. невидимый  smile 

поставь в цикле фильтр: если исходный цвет белый, значит поставить ему альфу FF, иначе - 0

или можешь полупрозрачность на текст наложить: вместо нуля что-нить вроде 7F

если тебе нужна простая иконка, без полутонов, то заморачиваться с BITMAPV5HEADER не было смысла,
обычная иконка, формируемая двумя растрами (через BITMAPINFOHEADER), и так имеет прозрачные зоны


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


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3993
Регистрация: 14.6.2006

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



Не получается сделать иконку прозрачной (маска прозрачности - черная)
при 16 битном цвете:

Код

HBITMAP dib = CreateDIBSection(NULL, &bmi, DIB_RGB_COLORS, (void **)&dst, NULL, 0);

bpl = 4 * bmp.bmWidth; /* bytes per line */
src = (UCHAR *)lpbitmap;
for (y = 0; y < bmp.bmHeight; y++, src += bpl) {
    tmp = src;
    for (x = 0; x < bmp.bmWidth; x++) {
        if (wBitsPixel > 16) {
            alpha = tmp[3];

            dst[0] = tmp[0] * alpha / 255;
            dst[1] = tmp[1] * alpha / 255;
            dst[2] = tmp[2] * alpha / 255;
            dst[3] = alpha;
        } else {
            /* ??????????????????? */
            dst[0] = tmp[0];
            dst[1] = tmp[1];
            dst[2] = tmp[2];
            dst[3] = tmp[3];
        }

        dst += 2;
        tmp += 4;
    }
}



Присоединённый файл ( Кол-во скачиваний: 15 )
Присоединённый файл  Pic.png 2,39 Kb


--------------------
PM WWW ICQ Skype Jabber   Вверх
Alca
Дата 12.2.2013, 06:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3993
Регистрация: 14.6.2006

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



После таких манипуляций (по другому это никак не назовешь):
Код

dst[0] = tmp[0];
dst[1] = tmp[1];
dst[2] = tmp[2];
dst[3] = tmp[2];  // <<<<

получилось вот это:


Присоединённый файл ( Кол-во скачиваний: 11 )
Присоединённый файл  Pic.png 1,20 Kb


--------------------
PM WWW ICQ Skype Jabber   Вверх
artsb
Дата 12.2.2013, 08:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2280
Регистрация: 17.7.2007
Где: центр Вселенной

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



Я не помню где лежит альфа канал. Если последний, то можно попробовать так:
Код

dst[0] = tmp[0];
dst[1] = tmp[1];
dst[2] = tmp[2];
dst[3] = (tmp[3] > 255. / 2.)?255:0;  // <<<<


Это сообщение отредактировал(а) artsb - 12.2.2013, 08:50


--------------------
Чем отличается умный человек от мудрого?
Умный - выпутается из любой ситуации.
Мудрый - просто в неё не попадёт.
PM MAIL   Вверх
GremlinProg
Дата 12.2.2013, 08:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Alca, а какой у тебя там biCompression?
Цитата(BITMAPINFOHEADER @  MSDN)

If the biCompression member of the BITMAPINFOHEADER is BI_BITFIELDS, the bmiColors member contains three DWORD color masks that specify the red, green, and blue components, respectively, of each pixel. Each WORD in the bitmap array represents a single pixel.




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


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3993
Регистрация: 14.6.2006

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



Цитата

Alca, а какой у тебя там biCompression?


Код

bi.biCompression = BI_RGB;
bmi.bmiHeader.biCompression = BI_RGB;


Цитата

If the biCompression member of the BITMAPINFOHEADER is BI_BITFIELDS, the bmiColors member contains three DWORD color masks that specify the red, green, and blue components, respectively, of each pixel. Each WORD in the bitmap array represents a single pixel.

Попробывать сделать с  BI_BITFIELDS ?







--------------------
PM WWW ICQ Skype Jabber   Вверх
GremlinProg
Дата 12.2.2013, 12:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Цитата(Alca @  12.2.2013,  13:51 Найти цитируемый пост)
Попробывать сделать с  BI_BITFIELDS ?

Да, думаю это будет правильней, чтобы не подбирать "эфемерную" маску прозрачности.

Только обращай внимание, что каждая маска размером с DWORD,
и тут нет комментария по поводу, должна ли быть четвертая маска в случае с наличием "альфы",
или ее следует формировать взаимоисключением остальных трех.

Возможно придется делать и так и так, пока не будет найдено верное решение.

Не проще ли было использовать 8- и менее- битный формат для предоставления флагов? Там же цветов: раз-два и обчелся, их можно бы было держать отдельно в палитре, которая в таком случае располагается после BITMAPINFOHEADER. Там это простые RGBQUAD, у которых нет такой неопределенности с альфой.


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


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3993
Регистрация: 14.6.2006

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



Цитата

Не проще ли было использовать 8- и менее- битный формат для предоставления флагов? Там же цветов: раз-два и обчелся, их можно бы было держать отдельно в палитре, которая в таком случае располагается после BITMAPINFOHEADER. Там это простые RGBQUAD, у которых нет такой неопределенности с альфой.

есть какой-то просто пример?


--------------------
PM WWW ICQ Skype Jabber   Вверх
GremlinProg
Дата 12.2.2013, 13:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Понятных примеров не нашел.

Здесь все то же самое, что ты сделал, но вместо bmi - выделяй память на
Код

sizeof( BITMAPINFOHEADER ) + 256 * sizeof( RGBQUAD )

BITMAPINFOHEADER заполняешь как раньше, только ставишь 8 бит,
а таблицу цветов ниже заполняешь цветами, которыми будешь использовать.

Когда создашь DIB, у тебя будет указатель на байтовый массив - аналогичный тому, который у тебя сейчас 16-битный,
расчитывай ширину строки и заполняй каждый байт номером цвета из той таблицы цветов, что ты заполнял при создании.

Соответственно, альфу уже можно задать только в таблице цветов, поэтому, если два пиксела имеют одинаковые цвета, но разные альфы, индексы у них тоже разные.

Для обычных картинок это работает, но будет ли в этом случае использоваться альфа - не знаю, не проверял.


--------------------
"Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины."
PM WWW ICQ   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "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.1287 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


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

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