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

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

11.01.2011, 17:21. Показов 34762. Ответов 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
Ответ Создать тему
Новые блоги и статьи
Философия технологии
iceja 01.02.2026
На мой взгляд у человека в технических проектах остается роль генерального директора. Все остальное нейронки делают уже лучше человека. Они не могут нести предпринимательские риски, не могут. . .
SDL3 для Web (WebAssembly): Вывод текста со шрифтом TTF с помощью SDL3_ttf
8Observer8 01.02.2026
Содержание блога В этой пошаговой инструкции создадим с нуля веб-приложение, которое выводит текст в окне браузера. Запустим на Android на локальном сервере. Загрузим Release на бесплатный. . .
SDL3 для Web (WebAssembly): Сборка C/C++ проекта из консоли
8Observer8 30.01.2026
Содержание блога Если вы откроете примеры для начинающих на официальном репозитории SDL3 в папке: examples, то вы увидите, что все примеры используют следующие четыре обязательные функции, а. . .
SDL3 для Web (WebAssembly): Установка Emscripten SDK (emsdk) и CMake для сборки C и C++ приложений в Wasm
8Observer8 30.01.2026
Содержание блога Для того чтобы скачать Emscripten SDK (emsdk) необходимо сначало скачать и уставить Git: Install for Windows. Следуйте стандартной процедуре установки Git через установщик. . . .
SDL3 для Android: Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 29.01.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами. Версия v3 была полностью переписана на Си, в. . .
Инструменты COM: Сохранение данный из VARIANT в файл и загрузка из файла в VARIANT
bedvit 28.01.2026
Сохранение базовых типов COM и массивов (одномерных или двухмерных) любой вложенности (деревья) в файл, с возможностью выбора алгоритмов сжатия и шифрования. Часть библиотеки BedvitCOM Использованы. . .
SDL3 для Android: Загрузка PNG с альфа-каналом с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 28.01.2026
Содержание блога SDL3 имеет собственные средства для загрузки и отображения PNG-файлов с альфа-каналом и базовой работы с ними. В этой инструкции используется функция SDL_LoadPNG(), которая. . .
SDL3 для Android: Загрузка PNG с альфа-каналом с помощью SDL3_image
8Observer8 27.01.2026
Содержание блога SDL3_image - это библиотека для загрузки и работы с изображениями. Эта пошаговая инструкция покажет, как загрузить и вывести на экран смартфона картинку с альфа-каналом, то есть с. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru