Форум программистов, компьютерный форум, киберфорум
C/C++: WinAPI
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.83/18: Рейтинг темы: голосов - 18, средняя оценка - 4.83
20 / 20 / 1
Регистрация: 30.01.2013
Сообщений: 99
1

Создание прозрачного окна на GDI+

12.02.2018, 02:57. Показов 3751. Ответов 15
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Доброго времени
Возник вопрос можно ли сделать вывод на экран картинки с прозрачными краями. По идее это должен быть апдейтер, но получается так что он вы водится без прозрачных краев.

как должно быть
https://www.cyberforum.ru/atta... 1518392762

и как получается с помощью win32 GDI+ через регионы обрезаю края и вывожу.
https://www.cyberforum.ru/atta... 1518393134

от чего зависит такой эффект вывода картинки?
буду очень вам признателен за любые ответы.
Миниатюры
Создание прозрачного окна на GDI+   Создание прозрачного окна на GDI+  
0
Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
12.02.2018, 02:57
Ответы с готовыми решениями:

Получение цвета прозрачного окна
Всем привет мне нужно получить цвет пикселей прозрачного окна. Обычно получаю цвет таким способом...

Создание прозрачного фона в GD
Ничего толкового нагуглить не смог, хотя подобная проблема возникает у многих. Проблемя в создании...

Создание прозрачного призрака-силуэта
Всем доброго времени суток! У меня есть довольно сложный объект, состоящий из N-го количества...

Создание прозрачного фона в тексте в Unity3D
Здравствуйте, возможно ли создать в Unity3d текст фон которого будет прозрачным, т.е внутри букв...

15
2710 / 864 / 327
Регистрация: 10.02.2018
Сообщений: 2,044
12.02.2018, 09:34 2
От альфы (прозрачности) зависит. На втором скрине, в левом нижнем углу как раз про неё речь под картинкой). Каждый пиксель картинки может быть не только полностью прозрачным или не прозрачным, но и иметь частичную прозрачность. На втором скрине ясно видно отсутствие полупрозрачностей.
0
20 / 20 / 1
Регистрация: 30.01.2013
Сообщений: 99
12.02.2018, 15:45  [ТС] 3
как можно добавить эту полу полупрозрачность, какие параметры за это отвечают?

Добавлено через 42 минуты
Готов не много денежкой вознаградить за помощь.
0
2710 / 864 / 327
Регистрация: 10.02.2018
Сообщений: 2,044
12.02.2018, 18:04 4
Прозрачность создаёт художник рисующий арт, она сохраняется в картинке. Если в вашей исходной картинке её нет, то нужно найти другую картинку, где она есть. Показать на экране можно с помощью "layered windows", например.
В приложении простенький пример.
Вложения
Тип файла: zip LayeredWin.zip (380.1 Кб, 26 просмотров)
0
28 / 27 / 11
Регистрация: 04.03.2010
Сообщений: 199
12.02.2018, 18:05 5
Цитата Сообщение от Sir1us Посмотреть сообщение
как можно добавить эту полу полупрозрачность, какие параметры за это отвечают?
Sir1us, для начала у вас должна быть картинка с полупрозрачностью в формате png.
Затем создаём окно, например, так:
C++
1
HWND my_window = CreateWindowEx(NULL, WndClassName, "Transparent", WS_POPUP, X, Y, Width, Height, HWND_DESKTOP, NULL, hInstance, NULL);
делаем окно многослойным:
C++
1
SetWindowLong(my_window, GWL_EXSTYLE, GetWindowLong(my_window, GWL_EXSTYLE) ^ WS_EX_LAYERED);
загружаем png-картинку
C++
1
Gdiplus::Bitmap *background_img = new Gdiplus::Bitmap(L"g:/test.png", false);
немного магии:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
BITMAPINFO BMI;
BMI.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
BMI.bmiHeader.biBitCount = 32;
BMI.bmiHeader.biCompression = BI_RGB;
BMI.bmiHeader.biWidth = background_img->GetWidth();
BMI.bmiHeader.biHeight = background_img->GetHeight();
BMI.bmiHeader.biPlanes = 1;
 
HDC screendc;
 
HBITMAP hbmp = CreateDIBSection(screendc, &BMI, DIB_RGB_COLORS, NULL, NULL, 0);
 
//получаем контекст
screendc = GetDC(my_window);
 
//создаём контекст, совместимый с screendc
HDC backdc = CreateCompatibleDC(screendc);
 
//загружаем в него HBITMAP
HBITMAP h_old_bmp = (HBITMAP)SelectObject(backdc, hbmp);
 
//устанавливаем параметры смешивания
BLENDFUNCTION bf;
bf.BlendOp = AC_SRC_OVER;
bf.BlendFlags = 0;
bf.SourceConstantAlpha = 0xff;//100%
bf.AlphaFormat = AC_SRC_ALPHA;
 
 
POINT pt1 = {0, 0};//новая позиция многослойного окна
POINT pt2 = {0, 0};//позиция слоя в контексте устройства
 
SIZE WndSize;//новый размер многослойного окна
WndSize.cx = Width;
WndSize.cy = Height;
рисуем в многослойное окно нашу картинку с прозрачностью:
C++
1
2
3
Graphics *graphics = new Graphics(backdc);
graphics->Clear(Color(0, 0, 0, 0));
graphics->DrawImage(background_img, 0, 0, Width, Height);
обновляем многослойное окно
C++
1
UpdateLayeredWindow(my_window, screendc, &pt1, &WndSize, backdc, &pt2, 0, &bf, ULW_ALPHA);
показываем окно на экран
C++
1
ShowWindow(my_window, SW_SHOW);
Получаем:
Создание прозрачного окна на GDI+
1
5280 / 2877 / 484
Регистрация: 05.10.2013
Сообщений: 7,650
Записей в блоге: 155
12.02.2018, 19:07 6
Sir1us, если у вас есть арт (картинка) без прозрачности, то можете скинуть рисунок в тему. Я знаю, как в редакторе GIMP (это бесплатный аналог фотошопа) добавить прозрачность.
1
20 / 20 / 1
Регистрация: 30.01.2013
Сообщений: 99
12.02.2018, 22:07  [ТС] 7
8Observer8 спасибо, но есть полностью PSD рисунок.

Вот такой результат выходит как советует Ygg это не совсем то что нужно
https://www.cyberforum.ru/atta... 1518461770

Насчет второго варианта не совсем разобрался, но вижу что оно делает сразу полупрозрачный фон.
буду сейчас разбираться дальше.

Нужно что бы вышло как на скрине
https://www.cyberforum.ru/atta... 1518461773
картинка идет можно сказать градиентом плавно переходит с заполненного фона цветом, в прозрачный.
Миниатюры
Создание прозрачного окна на GDI+   Создание прозрачного окна на GDI+  
0
2710 / 864 / 327
Регистрация: 10.02.2018
Сообщений: 2,044
12.02.2018, 23:06 8
Лучший ответ Сообщение было отмечено Sir1us как решение

Решение

В документации к этим окнам было сказано, что нужна premultyplay картинка. Т.е. цвета пикселей должны быть помножены на нормализованную прозрачность (при 8ми битах: alpha/255). Можно попробовать при загрузке картинки добавить преобразование или в редакторе опции поискать соответствующие.

Добавлено через 7 минут
Неправильно написал слово "premultiply"

Добавлено через 32 минуты
Как вариант, поставить после кода
C++
1
2
3
    // Get dimensions
    int iWidth = img.GetWidth();
    int iHeight = img.GetHeight();
что-то вроде этого
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
    if (img.GetBPP() == 32)
    {
        int iPitch = img.GetPitch();
        for (int y = 0; y < iHeight; y++)
        {
            unsigned char* pBuffer = (unsigned char*)img.GetBits() + iPitch*y;
            for (int x = 0; x < iWidth; x++)
            {
                unsigned uAlpha = pBuffer[3];
                pBuffer[0] = (unsigned char)(uAlpha * pBuffer[0] / 255);
                pBuffer[1] = (unsigned char)(uAlpha * pBuffer[1] / 255);
                pBuffer[2] = (unsigned char)(uAlpha * pBuffer[2] / 255);
                pBuffer += 4;
            }
        }
    }
не очень универсально, но вроде работает с приложенной картинкой.
1
20 / 20 / 1
Регистрация: 30.01.2013
Сообщений: 99
12.02.2018, 23:18  [ТС] 9
действительно очень хорошо выходит, добавите меня в скайп что бы я мог вас отблагодарить и уточнить нюансы sir1us_adm
0
2710 / 864 / 327
Регистрация: 10.02.2018
Сообщений: 2,044
12.02.2018, 23:39 10
Sir1us, смог помочь и хорошо, дополнительные благодарности излишни.
1
28 / 27 / 11
Регистрация: 04.03.2010
Сообщений: 199
12.02.2018, 23:51 11
Цитата Сообщение от Ygg Посмотреть сообщение
Как вариант, поставить после кода
Зачем нужно морочить человеку голову этим? Чтобы код сработал, нужно загружать предварительно подготовленную png-картинку, а не загружать всё подряд и потом только обрабатывать "неправильную" картинку уже дополнительным кодом. Костыли какие-то...А если автор позже заменит картинку на подготовленную, что это получится? Естественно не то, что ожидается.
Многослойные окна - хорошая штука - можно делать всякие красивости. Но есть определённые сложности.
Как-то делал погодный информатор:
png-картинка
Название: 011.jpg
Просмотров: 133

Размер: 13.6 Кб
и результат
Название: 022.jpg
Просмотров: 132

Размер: 22.4 Кб
Правда пришлось еще поизвращаться с кнопками и надписями: это ж уже не обычное окно, а, по своей сути, - графический холст.
2
20 / 20 / 1
Регистрация: 30.01.2013
Сообщений: 99
13.02.2018, 00:32  [ТС] 12
предварительно подготовленную png-картинку
а как такую картинку подготавливать и что нужно использовать?
0
28 / 27 / 11
Регистрация: 04.03.2010
Сообщений: 199
13.02.2018, 00:47 13
Цитата Сообщение от Sir1us Посмотреть сообщение
а как такую картинку подготавливать и что нужно использовать?
я делаю так в Фотошопе: отключаю все фоновые слои (если есть), добиваюсь такого вида изображения, которое должно получится в результате. Затем File -> Save As / PNG, галочка "Interlaced" установлена.
Так что, если есть проблема с картинкой уже в вашей программе, то внимательно пересмотрите, всё ли вы лишнее отключили на этапе её создания в фотошоп.
1
20 / 20 / 1
Регистрация: 30.01.2013
Сообщений: 99
13.02.2018, 05:20  [ТС] 14
Igor-84
а вы можете выложить скомпилированный код? У меня не совсем получается изображение на экран.
0
28 / 27 / 11
Регистрация: 04.03.2010
Сообщений: 199
13.02.2018, 14:18 15
Цитата Сообщение от Sir1us Посмотреть сообщение
а вы можете выложить скомпилированный код?
Пожалуйста (exe + картинка), Splash.rar
Также попробуйте подкинуть в папку с программой своё png-изображение, только переименуйте файл в test.png.
0
45 / 33 / 15
Регистрация: 29.04.2014
Сообщений: 225
02.12.2018, 22:37 16
Не забудьте прибавить 127:
C++
1
2
3
4
5
6
7
8
9
10
for (int i = 0; i < img.GetWidth(); i++)
{
    for (int j = 0; j < img.GetHeight(); j++)
    {
        BYTE* ptr = (BYTE*)img.GetPixelAddress(i, j);
        ptr[0] = ((ptr[0] * ptr[3]) + 127) / 255;
        ptr[1] = ((ptr[1] * ptr[3]) + 127) / 255;
        ptr[2] = ((ptr[2] * ptr[3]) + 127) / 255;
    }
}
0
02.12.2018, 22:37
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
02.12.2018, 22:37
Помогаю со студенческими работами здесь

Есть ли в WPF полноценная замена GDI+? Чтобы можно было всё, что можно в GDI+? Просто думаю углубляться в работу с изображениями в WPF или GDI.
Ну собственно весь вопрос в заголовке темы.

GDI FillRect, видно мерцание на месте контрола при движении окна
WINAPI Я использую FillRect для очистки фона, WM_ERASEBKGRN заблокировал, отрисовка по таймеру...

Создание bmp средствами gdi
Добрый день! Передо мной встала задача создать bmp файл, состоящий из изображений отрезком и...

Создание классов геометрических фигур, рисование на GDI (MFC)
Нужно создать класс Shape, как некий родительский класс геометрических фигур, от которого будут...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
16
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru