Форум программистов, компьютерный форум, киберфорум
Visual C++
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.79/184: Рейтинг темы: голосов - 184, средняя оценка - 4.79
 Аватар для body90
467 / 344 / 19
Регистрация: 26.05.2009
Сообщений: 2,696

Вывод изображения WinAPI

11.01.2011, 17:21. Показов 34701. Ответов 23
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Здравствуйте! Нужно сделать что-то типа графического редоктора, который накладывает фильтры на изображения. С алгоритмами я знаком, на C# уже написал приложение(для "посмотреть как оно будет"), но нужно всё сделать на WinAPI. Подскажите, как с помощью WinAPI:
1) получить изображение из файла
2) иметь возможность получить/изменить цвет определенного пикселя
3) отобразить полученное изображение в окне
4) сохранить его в файл
Буду очень признателен за код, если никого не затруднит.
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
11.01.2011, 17:21
Ответы с готовыми решениями:

Вывод изображения в WinAPI
Вот не получается загрузить картинку Делаю по примеру найденому здесь на форуме Но у меня не находит файл #include <windows.h> ...

Вывод изображения из файла в окно (Winapi)
делаю так но выводит белый фон case WM_PAINT: hdc = BeginPaint(hWnd, &ps); hdc = BeginPaint(hWnd,...

Visual Studio 2008, WinAPI - Вывод изображения
Как вывести изображение на форму? В гугле искал, но там что-то ничего того,что я могу понять не нашёл =( Понял только , что...

23
 Аватар для body90
467 / 344 / 19
Регистрация: 26.05.2009
Сообщений: 2,696
12.01.2011, 22:30  [ТС]
Неужели никто не может помочь?
0
Модератор
Эксперт PythonЭксперт JavaЭксперт CЭксперт С++
 Аватар для easybudda
12843 / 7592 / 1766
Регистрация: 25.07.2009
Сообщений: 13,973
12.01.2011, 23:34
Лучший ответ Сообщение было отмечено как решение

Решение

body90, выводилка картинки в окошке есть, может пригодится...
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
#include <windows.h>
    
LRESULT CALLBACK PictViewWndProc(HWND, UINT, UINT, LONG);
 
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdParam, int nCmdShow){
    HWND hWnd;
    WNDCLASS WndClass;
    MSG Msg;
    char szClassName[] = "PictView";
    
    WndClass.style = CS_HREDRAW | CS_VREDRAW;
    WndClass.lpfnWndProc = PictViewWndProc;
    WndClass.cbClsExtra = 0;
    WndClass.cbWndExtra = 0;
    WndClass.hInstance = hInstance;
    WndClass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    WndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
    WndClass.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
    WndClass.lpszMenuName = NULL;
    WndClass.lpszClassName = szClassName;
    
    if ( ! RegisterClass(&WndClass) ){
        MessageBox(NULL, "Can't register class", "Error", MB_OK);
        return 0;
    }
    
    hWnd = CreateWindow(szClassName, "Picture View", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 
        CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL);
    if ( ! hWnd ){
        MessageBox(NULL, "Can't create window", "Error", MB_OK);
        return 0;
    }
    
    ShowWindow(hWnd, nCmdShow);
    UpdateWindow(hWnd);
    
    while ( GetMessage(&Msg, NULL, 0, 0) ){
        TranslateMessage(&Msg);
        DispatchMessage(&Msg);
    }
    return Msg.wParam;
}
 
LRESULT CALLBACK PictViewWndProc(HWND hWnd, UINT Message, UINT wParam, LONG lParam){
    HDC hDC, hCompatibleDC;
    PAINTSTRUCT PaintStruct;
    HANDLE hBitmap, hOldBitmap;
    RECT Rect;
    BITMAP Bitmap;
    
    switch ( Message ){
    case WM_PAINT :
        hDC = BeginPaint(hWnd, &PaintStruct);
        hBitmap = LoadImage(NULL, "picture.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
        GetObject(hBitmap, sizeof(BITMAP), &Bitmap);
        hCompatibleDC = CreateCompatibleDC(hDC);
        hOldBitmap = SelectObject(hCompatibleDC, hBitmap);
        GetClientRect(hWnd, &Rect);
        StretchBlt(hDC, 0, 0, Rect.right, Rect.bottom, hCompatibleDC, 0, 0, Bitmap.bmWidth, 
            Bitmap.bmHeight, SRCCOPY);
        SelectObject(hCompatibleDC, hOldBitmap);
        DeleteObject(hBitmap);
        DeleteDC(hCompatibleDC);
        EndPaint(hWnd, &PaintStruct);
        return 0;
    case WM_DESTROY :
        PostQuitMessage(0);
        return 0;
    }
    
    return DefWindowProc(hWnd, Message, wParam, lParam);
}
picture.bmp должен в одной папке с программой лежать.
8
 Аватар для body90
467 / 344 / 19
Регистрация: 26.05.2009
Сообщений: 2,696
13.01.2011, 14:02  [ТС]
А как получать и задавать цвет точки в изображении?

Добавлено через 13 часов 49 минут
Хоть функции для получения и задания цвета точки в битмапе скажите
0
 Аватар для body90
467 / 344 / 19
Регистрация: 26.05.2009
Сообщений: 2,696
15.01.2011, 05:47  [ТС]
Как связать HBITMAP и GetPixel()/SetPixel?
0
Модератор
Эксперт PythonЭксперт JavaЭксперт CЭксперт С++
 Аватар для easybudda
12843 / 7592 / 1766
Регистрация: 25.07.2009
Сообщений: 13,973
15.01.2011, 11:21
body90, на MSDN-ской странице с описанием GetPixel есть ссылки внизу
Bitmaps Overview
Bitmap Functions
там ничего интересного не нашлось?
На сколько я понимаю, hDC - это хендл контекста устройства (того самого, на которое изображение выводится)
Цитата Сообщение от easybudda Посмотреть сообщение
hDC = BeginPaint(hWnd, &PaintStruct);
2
 Аватар для body90
467 / 344 / 19
Регистрация: 26.05.2009
Сообщений: 2,696
15.01.2011, 11:55  [ТС]
Цитата Сообщение от easybudda Посмотреть сообщение
На сколько я понимаю, hDC - это хендл контекста устройства (того самого, на которое изображение выводится)
А как получить HDC изображения (битмапа)
0
Модератор
Эксперт PythonЭксперт JavaЭксперт CЭксперт С++
 Аватар для easybudda
12843 / 7592 / 1766
Регистрация: 25.07.2009
Сообщений: 13,973
15.01.2011, 12:55
Цитата Сообщение от body90 Посмотреть сообщение
А как получить HDC изображения (битмапа)
Не, Вы немного не правильно себе это представляете... Пиксели нужно искать уже не в картинке, а в том объекте, в который Вы её загрузили.
Цитата Сообщение от easybudda Посмотреть сообщение
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
case WM_PAINT :
  hDC = BeginPaint(hWnd, &PaintStruct);
  hBitmap = LoadImage(NULL, "picture.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
  GetObject(hBitmap, sizeof(BITMAP), &Bitmap);
  hCompatibleDC = CreateCompatibleDC(hDC);
  hOldBitmap = SelectObject(hCompatibleDC, hBitmap);
  GetClientRect(hWnd, &Rect);
  StretchBlt(hDC, 0, 0, Rect.right, Rect.bottom, hCompatibleDC, 0, 0, Bitmap.bmWidth, 
  Bitmap.bmHeight, SRCCOPY);
  SelectObject(hCompatibleDC, hOldBitmap);
  DeleteObject(hBitmap);
  DeleteDC(hCompatibleDC);
  EndPaint(hWnd, &PaintStruct);
  return 0;
Вот этот кусок разберите, станет немного понятнее, что искать нужно...
2
 Аватар для body90
467 / 344 / 19
Регистрация: 26.05.2009
Сообщений: 2,696
15.01.2011, 13:05  [ТС]
Тут понятно. Выводит картинку в окно. Но разве правильно будет применять фильтры к картинке, которая уже нарисована в окне? Тем более как я ее потом сохраню в файл? Получить цвет пикселя из окна или экрана я могу. Но как это сделать для изображения? Не может быть, что только по байтам всё читать. Может как-то с помощью GDI+ можно?
0
 Аватар для Kastaneda
5232 / 3205 / 362
Регистрация: 12.12.2009
Сообщений: 8,143
Записей в блоге: 2
15.01.2011, 20:57
body90, а чем GetPixel() не устраивает?
Если все таки не устраивает, то читаем про формат .bmp. Можно просто считывать байты прям из картинки, значение байт - есть цвета картинки в формате RGB. Но там не с первого байта читать надо, в общем почитайте, я на память не помню.

Добавлено через 2 минуты
Нет, там даже не в RGB, сейчас в википедии глянул. Советую, там достаточно информации.
1
 Аватар для body90
467 / 344 / 19
Регистрация: 26.05.2009
Сообщений: 2,696
15.01.2011, 21:01  [ТС]
Цитата Сообщение от Kastaneda Посмотреть сообщение
body90, а чем GetPixel() не устраивает?
Меня вообще больше чем устраивает. Но я не знаю как им воспользоваться. Как работать с помощью GetPixel() с HBITMAP?
0
 Аватар для Kastaneda
5232 / 3205 / 362
Регистрация: 12.12.2009
Сообщений: 8,143
Записей в блоге: 2
15.01.2011, 21:09
GetPixel() считывает цвет пикселя в определенных координатах экрана. С HBITMAP его ни как не используешь. Тут смотря для каких целей нужен цвет пикселя, может и GetPixel() подойдет.
Если мне не изменяет память, то прототип выглядет так GetPixel(HDC DC,DWORD X, DWORD Y)

Добавлено через 1 минуту
например
C++
1
2
HDC dc=GetDC(0);
COLORREF clrf=GetPixel(dc,0,0);
получаем цвет пикселя в левом верхнем углу экрана (не зависимо от того, какое окно открыто)
1
 Аватар для body90
467 / 344 / 19
Регистрация: 26.05.2009
Сообщений: 2,696
15.01.2011, 21:18  [ТС]
В том то и проблема, что мне нужно накладывать фильтры на изображение. Я его загружаю, а дальше мне надо получать цвет каждой точки и работать с ним. Совсем не хочется работать с байтами. Тем более на сколько я помню там еще всё зависит от цветовой палитры.
0
 Аватар для Kastaneda
5232 / 3205 / 362
Регистрация: 12.12.2009
Сообщений: 8,143
Записей в блоге: 2
15.01.2011, 21:24
Цитата Сообщение от body90 Посмотреть сообщение
мне нужно накладывать фильтры на изображение
Тогда наверно напрямую с байтами, GetPixel() тут не очень удобно использовать. С байтами работать не так страшно, как кажется) Нужно просто понять структуру файла, а дальше совсем просто)
1
 Аватар для body90
467 / 344 / 19
Регистрация: 26.05.2009
Сообщений: 2,696
16.01.2011, 00:55  [ТС]
Приложение нужно подстраивать под разные палитры? А как быть со сжатием?

Добавлено через 11 минут
Для начала попробую сделать всё же чтение по байтам для 24-байтного изображения. Можете помочь с кодом: как узнать высоту, ширину и с какого места начинаются байты изображения?

Добавлено через 2 часа 40 минут
Кстати, а с помощью GDI+ никак нельзя получать цвет пикселей?
0
 Аватар для body90
467 / 344 / 19
Регистрация: 26.05.2009
Сообщений: 2,696
16.01.2011, 19:59  [ТС]
Вот попытался загрузить изображение с помощью GDI+ и нарисовать его. Подскажите, почему ничего не рисуется? Что я пропустил?
Вложения
Тип файла: rar GDI.rar (848.5 Кб, 56 просмотров)
0
 Аватар для body90
467 / 344 / 19
Регистрация: 26.05.2009
Сообщений: 2,696
20.01.2011, 20:51  [ТС]
Неужели всем так тяжело посмотреть и сказать в чем проблема?

Добавлено через 17 часов 2 минуты
Всё, нашел в чем проблема: не инициализировал GDI+. Спасибо всем, кто не ответил!
0
230 / 0 / 1
Регистрация: 15.06.2011
Сообщений: 4
15.06.2011, 18:42
Лучший ответ Сообщение было отмечено как решение

Решение

Не стану создавать новую тему.
В примере из третьего поста в обработчике WM_PAINT каждый раз создается битмап и загружается из файла picture.bmp.
А вот тут утверждается, что выбранный объект надо удалять после использования.
Зачем это нужно? Не будет ли правильнее создать битмап и хендл глобальными переменными, загрузить изображение в winmain и удалить их в обработчике закрытия окна, например?
0
Модератор
Эксперт PythonЭксперт JavaЭксперт CЭксперт С++
 Аватар для easybudda
12843 / 7592 / 1766
Регистрация: 25.07.2009
Сообщений: 13,973
15.06.2011, 23:19
Цитата Сообщение от lavrentiy Посмотреть сообщение
Не будет ли правильнее создать битмап и хендл глобальными переменными, загрузить изображение в winmain и удалить их в обработчике закрытия окна, например?
Да может так и лучше... Пример из книжки по winapi, наверняка многое "за уши притянуто"...
3
 Аватар для xAtom
935 / 760 / 299
Регистрация: 09.12.2010
Сообщений: 1,346
Записей в блоге: 1
16.06.2011, 15:34
Лучший ответ Сообщение было отмечено как решение

Решение

Вот такой вариант работы с файлом BMP. Покажу не большой пример как быстро получить доступ к массиву пикселов без обращения медленной функции режима ядра SetPixel/SetPixelV - но с ними тоже интересно поработать но медленно, при получение массива пикселей возможно быстро организовать разнообразные фильтры, сглаживания Гауссого, Лапласа, резкости и т.п.

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
// Глобальные объекты
HBITMAP    bit     = NULL;
HDC          dc      = NULL;
BYTE*       buffer = NULL;
DWORD     bsize   = 0U;
 
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    int wmId, wmEvent;
    PAINTSTRUCT ps;
 
    switch (message) {
    case WM_DESTROY: {  // Событие возникает при уничтожение окна
 
        if(buffer)
             delete[] buffer;
        buffer = NULL;
        DeleteObject(bit);
        DeleteDC(dc);
        PostQuitMessage(0);
    } break;
    case WM_CREATE: {  // создание совместимого контекста и объект битмап из файла
 
bit = (HBITMAP) ::LoadImage((HINSTANCE) GetWindowLong(hWnd, GWL_HINSTANCE),  "X:\\atom.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE | LR_CREATEDIBSECTION);
    BITMAP b;
           ZeroMemory(&b, sizeof(BITMAP));
    GetObject(bit, sizeof(BITMAP), (LPVOID)&b);
    bsize = b.bmWidth * b.bmHeight * b.bmBitsPixel;
           buffer = new  BYTE[ bsize ];
           dc = ::CreateCompatibleDC( GetDC(hWnd) );
 
if(! bit)
    MessageBox(hWnd, "Ошибка при загрузки файла !!!", "BITMAP ERROR", MB_OK | MB_ICONERROR);
 
} break;
case WM_PAINT: {   // Рисование в окне
 
    BeginPaint(hWnd, &ps);
 
    if(bit) {
          BITMAP b;
          ZeroMemory(&b, sizeof(BITMAP));
          GetObject(bit, sizeof(BITMAP), (LPVOID)&b);
          SelectObject(dc, bit);
          BitBlt(ps.hdc, 0, 0, b.bmWidth, b.bmHeight,  dc, 0, 0, SRCCOPY);
    }
 
    EndPaint(hWnd, &ps);
 
    } break;
case WM_LBUTTONDOWN: {  // при щёлкание левой кнокпи мыши изображение будет светлеть
                 
     if(buffer) {
        GetBitmapBits(bit, bsize, (LPVOID) buffer);
        for(DWORD  i = 0; i < bsize; i++) 
             *((buffer) + i) = min( *((buffer) + i) + 10, 255);
                            
        SetBitmapBits(bit, bsize, (CONST VOID*) buffer);
        RECT  rect;
        GetClientRect(hWnd, &rect);
        InvalidateRect(hWnd, &rect, FALSE);
    }
                            
} break;
case WM_RBUTTONDOWN: {  // при щёлкание правой кнопки мыши изображение будет темнеть
 
         if(buffer) {
    GetBitmapBits(bit, bsize, (LPVOID) buffer);
 
    for(DWORD  i = 0; i < bsize; i++) 
          *((buffer) + i) = max( *((buffer) + i) - 10, 55);
                            
    SetBitmapBits(bit, bsize, (CONST VOID*) buffer);
    RECT  rect;
    GetClientRect(hWnd, &rect);
    InvalidateRect(hWnd, &rect, FALSE);
       }
} break;
case WM_KEYDOWN: {  // Нажмите на любую клавишу, изображение станет чёрно-белым 
         //  чёрно белое изображение
       // Медленный доступ к пикселам, обусловлен переключение в режим ядра gdi
      BITMAP b;
      ZeroMemory(&b, sizeof(BITMAP));
      GetObject(bit, sizeof(BITMAP), (LPVOID)&b);
     for(DWORD x = 0U; x < b.bmWidth; x++) {
    for(DWORD  y = 0U; y < b.bmHeight; y++) {
        COLORREF  color = GetPixel(dc, x, y);
        color = RGB( color, color, color);   
        SetPixelV(dc, x, y, color);
    }
    }         
    RECT  rect;
    GetClientRect(hWnd, &rect);
    InvalidateRect(hWnd, &rect, FALSE);
 } break;
 default:
    return DefWindowProc(hWnd, message, wParam, lParam);
   }
   return 0;
}
3
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
16.06.2011, 15:34
Помогаю со студенческими работами здесь

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

Поворот bmp изображения на 90 градусов winapi
8) Написать программу, которая читает с диска *.bmp файл и выводит его в окно приложения. При помощи потока организовать поворот...

Вывод изображения поверх другого изображения
Привет, как правильнее сделать такую манипуляцию нужно на картинке вывести справа вверху КРАСНЫЙ КРУГ как на изображении которое...

Сохранение изображения jpg/png в базу данных средствами С++ и WinAPI с последующим извлечением оного из БД
Можно ли с использованием C++ на winApi сохранить изображение (png,jpeg) в какую нибудь переменную , потом сохранить все это в MysQL , а...

Вывод изображения с БД и размер изображения
&lt;div id=&quot;block-3&quot; &lt;?php $query = mysql_query(&quot;SELECT * FROM table_photos&quot; ,$link); $array = mysql_fetch_array($query); do { ...


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
Thinkpad X220 Tablet — это лучший бюджетный ноутбук для учёбы, точка.
Programma_Boinc 23.12.2025
Рецензия / Мнение/ Перевод Ниже машинный перевод статьи The Thinkpad X220 Tablet is the best budget school laptop period . Thinkpad X220 Tablet — это лучший бюджетный ноутбук для учёбы,. . .
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Как объединить две одинаковые БД Access с разными данными
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
Мысли в слух
kumehtar 18.11.2025
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru