Форум программистов, компьютерный форум, киберфорум
C/C++: WinAPI
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.55/11: Рейтинг темы: голосов - 11, средняя оценка - 4.55
 Аватар для Аким2020
6 / 5 / 1
Регистрация: 05.10.2020
Сообщений: 122

Открытие пнг файла с сохранением прозрачного фона

28.05.2021, 23:54. Показов 2215. Ответов 2

Студворк — интернет-сервис помощи студентам
Как вывести png картинку в gdi+ с сохранением прозрачного фона, и при этом используя кадровый буфер? Сейчас фон у картинки - белый.

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
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
#include <Windows.h>
#include <iostream>
#include "RectangleShape.h"
#include <gdiplus.h>
#pragma comment(lib, "gdiplus.lib")
 
 
 
HWND window_hwnd;
HDC window_hdc;
RECT client_rect;
HDC memDC;
HBITMAP memBM;
 
 
class Image {
 
    friend void drawPNG(Image& image);
 
private:
 
    LPCWSTR file_path_;
    int x_, y_, width_, height_;
    HBITMAP hbitmap_;
    int r_w_, r_h_;
 
public:
    
 
    Image(LPCWSTR file_path, int x, int y, int width, int height) {
        file_path_ = file_path;
        x_ = x;
        y_ = y;
        width_ = width;
        height_ = height;
 
        Gdiplus::Bitmap bitmap(file_path_);
        UINT w = bitmap.GetWidth(), h = bitmap.GetHeight();
        r_w_ = w;
        r_h_ = h;
        bitmap.GetHBITMAP(Gdiplus::Color::Transparent, &hbitmap_);
    }
 
 
 
    ~Image() {
        DeleteObject(hbitmap_);
    }
};
 
 
void clear() {
    SelectObject(memDC, memBM);
    SelectObject(memDC, GetStockObject(DC_BRUSH));
    SetDCBrushColor(memDC, RGB(255, 0, 0));
    Rectangle(memDC, client_rect.left, client_rect.top, client_rect.right, client_rect.bottom);
}
 
void drawPNG(Image& image) {
 
    HDC bmpDC = CreateCompatibleDC(window_hdc);
    SelectObject(bmpDC, image.hbitmap_);
 
    StretchBlt(memDC, image.x_, image.y_, image.width_, image.height_, bmpDC, 0, 0,
        image.r_w_, image.r_h_, SRCCOPY);
 
    DeleteDC(bmpDC);
}
 
 
void display() {
    BitBlt(window_hdc, 0, 0, client_rect.right - client_rect.left, client_rect.bottom - client_rect.top, memDC, 0, 0, SRCCOPY);
}
 
 
 
LRESULT CALLBACK window_procedure(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam) {
    if (message == WM_DESTROY) {
        exit(1);
    }
 
    else if (message == WM_SIZE) {
        GetClientRect(window_hwnd, &client_rect);
    }
 
    else {
        return DefWindowProc(hwnd, message, wparam, lparam);
    }
}
 
 
 
int main() {
    ULONG_PTR gdiToken;
    Gdiplus::GdiplusStartupInput gdiInput;
    Gdiplus::GdiplusStartup(&gdiToken, &gdiInput, NULL);
 
    WNDCLASSW window_class;
    memset(&window_class, 0, sizeof(WNDCLASSW));
        window_class.lpszClassName = L"window";
        window_class.lpfnWndProc = window_procedure;
    RegisterClassW(&window_class);
 
    window_hwnd = CreateWindowEx(WS_EX_TOPMOST, L"window", L"Anim", WS_OVERLAPPEDWINDOW & ~WS_THICKFRAME & ~WS_MAXIMIZEBOX, CW_USEDEFAULT, CW_USEDEFAULT, 800, 600, NULL, NULL, NULL, NULL);
 
    window_hdc = GetDC(window_hwnd);
    GetClientRect(window_hwnd, &client_rect);
    memDC = CreateCompatibleDC(window_hdc);
    memBM = CreateCompatibleBitmap(window_hdc, client_rect.right - client_rect.left, client_rect.bottom - client_rect.top);
    ShowWindow(window_hwnd, SW_SHOWNORMAL);
    MSG msg;
 
    Image image(L"D:\\ramka.png", 0, 0, 700, 600);
 
    while (true) {
        if (PeekMessageA(&msg, 0, NULL, NULL, PM_REMOVE)) {
            DispatchMessage(&msg);
        }
 
        
        clear();
        drawPNG(image);
        display();
    }
 
    DeleteObject(memBM);
    DeleteDC(memDC);
    Gdiplus::GdiplusShutdown(gdiToken);
 
 
    return 0;
}
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
28.05.2021, 23:54
Ответы с готовыми решениями:

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

Iframe Нету прозрачного фона
Собственно дело вот в чем. Я сделал презентацию на сайт и конвертировал ее с помощью iSpring Pro в HTML. Загрузил все что надо. Сделал...

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

2
6772 / 4565 / 1844
Регистрация: 07.05.2019
Сообщений: 13,726
29.05.2021, 10:58
Цитата Сообщение от Аким2020 Посмотреть сообщение
Как вывести png картинку в gdi+ с сохранением прозрачного фона, и при этом используя кадровый буфер? Сейчас фон у картинки - белый.
Не знаю, что такое "кадровый буфер", но, как минимум, её надо выводить в обработчике WM_PAINT, а не где попало
0
2735 / 890 / 331
Регистрация: 10.02.2018
Сообщений: 2,111
29.05.2021, 11:32
Проект один у меня сохранился. Может это не совсем то, что нужно. Вывод картинки с альфой в нём делается, но функциями gdi+. Приведу часть кода, отвечающая за работу с gdi+, проект целиком в архиве:
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
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
#include "stdafx.h"
#include "MyGdiplus.h"
 
//-------------------------------------------------------------------------------------------------
// вспомогательный класс для загрузки изображения из памяти
//-------------------------------------------------------------------------------------------------
#include "MyStream.h"
 
//-------------------------------------------------------------------------------------------------
// заводим экземпляр
//-------------------------------------------------------------------------------------------------
MyGdiplus myGdi;
 
//-------------------------------------------------------------------------------------------------
MyGdiplus::MyGdiplus()
{
    m_token = 0;
    m_offscreen = 0;
    m_image = 0;
}
 
//-------------------------------------------------------------------------------------------------
MyGdiplus::~MyGdiplus()
{
}
 
//-------------------------------------------------------------------------------------------------
// инициализация библиотеки перед началом работы с GDI+
//-------------------------------------------------------------------------------------------------
void MyGdiplus::Init()
{
    Gdiplus::GdiplusStartupInput gdiStartupInput;
    if (Gdiplus::GdiplusStartup(&m_token, &gdiStartupInput, NULL) != Gdiplus::Ok)
        MessageBox(0, TEXT("GdiplusStartup"), TEXT("ERROR"), MB_ICONERROR);
 
    // получим некоторые дефолтные настройки
    Gdiplus::Graphics gr(GetDesktopWindow());
    Gdiplus::Bitmap bm(1, 1, &gr);
}
 
//-------------------------------------------------------------------------------------------------
// создание контекста для рисования вне экрана
//-------------------------------------------------------------------------------------------------
void MyGdiplus::InitOffScreen()
{
    m_offscreen = new Gdiplus::Bitmap(screenW, screenH, PixelFormat32bppRGB);
    if (!m_offscreen)
        MessageBox(0, TEXT("GdiInitOffScreen"), TEXT("ERROR"), MB_ICONERROR);
}
 
//-------------------------------------------------------------------------------------------------
// загрузка изображения из файла
//-------------------------------------------------------------------------------------------------
void MyGdiplus::LoadImageFile(const wchar_t* file)
{
    if (m_image)
    {
        delete m_image;
        m_image = 0;
    }
 
    if (!file)
        return;
 
    m_image = new Gdiplus::Bitmap(file);
}
 
//-------------------------------------------------------------------------------------------------
// загрузка картинки из ресурсов (из памяти приложения)
// ресурс заменяется загрузкой файла в память и открытием из памяти
//-------------------------------------------------------------------------------------------------
void MyGdiplus::LoadFromResurce(const wchar_t* file)
{
    // удаляем старую картинку
    if (m_image)
    {
        delete m_image;
        m_image = 0;
    }
 
    if (!file)
        return;
 
    // читаем картинку в память
    MyStream* stream = new MyStream;
    stream->Prepare(file);
 
    // загружаем из памяти
    m_image = new Gdiplus::Bitmap(stream);
 
    // уменьшаем счётчик использований интерфейса
    stream->Release();
}
 
//-------------------------------------------------------------------------------------------------
// деинициализация библиотеки после работы с GDI+
//-------------------------------------------------------------------------------------------------
void MyGdiplus::Clean()
{
    if (m_image)
    {
        delete m_image;
        m_image = 0;
    }
 
    if (m_offscreen)
    {
        delete m_offscreen;
        m_offscreen = 0;
    }
 
    Gdiplus::GdiplusShutdown(m_token);
}
 
//-------------------------------------------------------------------------------------------------
void MyGdiplus::Draw(HWND wnd)
{
    static int tFill, tFillA, tImage, tText, tOff, tBlt;
    LARGE_INTEGER lFreq, lStart, lFill, lFillA, lImage, lText, lBlt;
    QueryPerformanceFrequency(&lFreq);
    QueryPerformanceCounter(&lStart);
 
    // рисуем картинку вне экрана
    Gdiplus::Graphics offscreen(m_offscreen);
    Gdiplus::SolidBrush whiteBrush(Gdiplus::Color(255, 255, 255));
    Gdiplus::SolidBrush darkBrush(Gdiplus::Color(180, 0, 0, 0));
    Gdiplus::SolidBrush redBrush(Gdiplus::Color(255, 0, 0));
    Gdiplus::SolidBrush greenBrush(Gdiplus::Color(0, 255, 0));
    Gdiplus::SolidBrush blueBrush(Gdiplus::Color(0, 0, 255));
    // разноцветные прямоуголькики
    offscreen.FillRectangle(&whiteBrush, 0, 0, screenW, screenH);
    offscreen.FillRectangle(&redBrush, 0, 0, screenW, screenH/3);
    offscreen.FillRectangle(&blueBrush, 0, screenH*2/3, screenW, screenH/3);
    offscreen.FillRectangle(&greenBrush, 0, 0, screenW/3, screenH);
    QueryPerformanceCounter(&lFill);
    // полупрозрачное затемнение
    offscreen.FillRectangle(&darkBrush, screenW/4, screenH/4, screenW/2, screenH/2);
    QueryPerformanceCounter(&lFillA);
    // картинка (наложение с альфой, если она есть)
    if (m_image)
    {
        // единые единицы измерения длин, что бы избежать лишнего масштабирования
        m_image->SetResolution(offscreen.GetDpiX(), offscreen.GetDpiY());
        // размеры картинки в пикселях
        int cx = m_image->GetWidth();
        int cy = m_image->GetHeight();
        // если картинка меньше экрана
        if ((cx < screenW) && (cy < screenH))
        {
            // накладываем по центру
            int x = (screenW - cx)/2;
            int y = (screenH - cy)/2;
            offscreen.DrawImage(m_image, x, y, cx, cy);
        }
        else
        {
            // масштабируем по размеру окна
            offscreen.DrawImage(m_image, Gdiplus::Rect(0,0,screenW,screenH), 0, 0, cx, cy, Gdiplus::UnitPixel);
        }
    }
    QueryPerformanceCounter(&lImage);
    // текст с информацией и замерами времени отрисовки
    Gdiplus::Font font(L"Arial", 16);
    wchar_t wcText[256];
    wsprintfW(wcText, L"Нажмите ПКМ для загрузки файла\n\nВремя отрисовки (мс):\n заливка=%d\n заливка с альфой=%d\n картинка=%d\n текст=%d\n общее=%d\n перенос на экран=%d", tFill, tFillA, tImage, tText, tOff, tBlt);
    offscreen.DrawString(wcText, wcslen(wcText), &font, Gdiplus::PointF(screenW/3, screenH/3), &whiteBrush);
    QueryPerformanceCounter(&lText);
 
    // копируем на экран
    Gdiplus::Graphics screen(wnd);
    screen.DrawImage(m_offscreen, 0, 0, screenW, screenH);
    QueryPerformanceCounter(&lBlt);
 
    tFill = int((lFill.QuadPart - lStart.QuadPart)*1000/lFreq.QuadPart);
    tFillA = int((lFillA.QuadPart - lFill.QuadPart)*1000/lFreq.QuadPart);
    tImage = int((lImage.QuadPart - lFillA.QuadPart)*1000/lFreq.QuadPart);
    tText = int((lText.QuadPart - lImage.QuadPart)*1000/lFreq.QuadPart);
    tOff = int((lImage.QuadPart - lStart.QuadPart)*1000/lFreq.QuadPart);
    tBlt = int((lBlt.QuadPart - lText.QuadPart)*1000/lFreq.QuadPart);
}
 
//-------------------------------------------------------------------------------------------------
Вложения
Тип файла: zip 01_GdiPlus.zip (8.3 Кб, 5 просмотров)
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
29.05.2021, 11:32
Помогаю со студенческими работами здесь

Рендер спрайтов, удаление прозрачного фона Unity
Народ всем салют. Имеется такая проблема есть изображение, в этом изображении середина прозрачная(Для понимания представите пончик у...

Вместо прозрачного фона вставляется черный цвет
Добрый день. Вот такая проблема вместо прозрачного фона вставляется черный цвет. Скрин прикрепил.

Реализация прозрачного фона для нескольких слоёв изображений
Есть некое фото (как задний фон - на рисунке это дома), так же на этот фон я накладываю желтый полупрозрачный слой. Далее мне надо...

Пропадание прозрачного фона при плавном перемещении объекта
на форме с фоновой картинкой есть pictureBox, который на клик плавно по событию таймера перемещается в определенную точку. Проблема:...

Как задать ширину прозрачного фона текста для корректного отображения
Добрый день. У меня возникла такая вот проблема: на сайте нужно сделать небольшой блок с заголовком, при этом фон-блок должен быть...


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

Или воспользуйтесь поиском по форуму:
3
Ответ Создать тему
Новые блоги и статьи
Модульная разработка через nuget packages
DevAlt 07.03.2026
Сложившийся в . Net-среде способ разработки чаще всего предполагает монорепозиторий в котором находятся все исходники. При создании нового решения, мы просто добавляем нужные проекты и имеем. . .
Модульный подход на примере F#
DevAlt 06.03.2026
В блоге дяди Боба наткнулся на такое определение: В этой книге («Подход, основанный на вариантах использования») Ивар утверждает, что архитектура программного обеспечения — это структуры,. . .
Управление камерой с помощью скрипта OrbitControls.js на Three.js: Вращение, зум и панорамирование
8Observer8 05.03.2026
Содержание блога Финальная демка в браузере работает на Desktop и мобильных браузерах. Итоговый код: orbit-controls-threejs-js. zip. Сканируйте QR-код на мобильном. Вращайте камеру одним пальцем,. . .
SDL3 для Web (WebAssembly): Синхронизация спрайтов SDL3 и тел Box2D
8Observer8 04.03.2026
Содержание блога Финальная демка в браузере. Итоговый код: finish-sync-physics-sprites-sdl3-c. zip На первой гифке отладочные линии отключены, а на второй включены:. . .
SDL3 для Web (WebAssembly): Идентификация объектов на Box2D v3 - использование userData и событий коллизий
8Observer8 02.03.2026
Содержание блога Финальная демка в браузере. Итоговый код: finish-collision-events-sdl3-c. zip Сканируйте QR-код на мобильном и вы увидите, что появится джойстик для управления главным героем. . . .
Реалии
Hrethgir 01.03.2026
Нет, я не закончил до сих пор симулятор. Эта задача сложнее. Не получилось уйти в плавсостав, но оно и к лучшему, возможно. Точнее получалось - но сварщиком в палубную команду, а это значит, в моём. . .
Ритм жизни
kumehtar 27.02.2026
Иногда приходится жить в ритме, где дел становится всё больше, а вовлечения в происходящее — всё меньше. Плотный график не даёт вниманию закрепиться ни на одном событии. Утро начинается с быстрых,. . .
SDL3 для Web (WebAssembly): Сборка библиотек: SDL3, Box2D, FreeType, SDL3_ttf, SDL3_mixer и SDL3_image из исходников с помощью CMake и Emscripten
8Observer8 27.02.2026
Недавно вышла версия 3. 4. 2 библиотеки SDL3. На странице официальной релиза доступны исходники, готовые DLL (для x86, x64, arm64), а также библиотеки для разработки под Android, MinGW и Visual Studio. . . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru