Форум программистов, компьютерный форум, киберфорум
C/C++: WinAPI
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.84/25: Рейтинг темы: голосов - 25, средняя оценка - 4.84
 Аватар для Avaddon74
571 / 353 / 133
Регистрация: 15.09.2017
Сообщений: 1,239

Способы получения цвета пикселя экрана

26.07.2018, 17:32. Показов 5083. Ответов 7
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Доброго времени суток!

Столкнулся с проблемой при получении цвета пикселя экрана, функция GetPixel работает слишком медленно, порядка 30 милисек. на один пиксель. Мне нужно получить цвета пикселей области экрана, например 30х100.
Каким способом это можно еще реализовать?
1
Лучшие ответы (1)
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
26.07.2018, 17:32
Ответы с готовыми решениями:

Способы получения скриншота экрана
Всем привет. Есть ли способ сделать скрин экрана помимо использования метода CopyFromScreen? Мне необходимо реализовать потоковую...

Как увидеть значение цвета пикселя экрана?
Ситуация такая: надо увидеть значение цвета пикселя экрана, чтоб забить его в константу для дальнейшего сравнения. Подскажите, как это...

Отслеживание определенного цвета пикселя в квадрате в центре экрана
var Dc: HDC; Pix: Cardinal; X: Integer; Y: Integer; begin Dc:=GetDC(0); for i := 240 to 840 do for j := 610...

7
2735 / 890 / 331
Регистрация: 10.02.2018
Сообщений: 2,109
26.07.2018, 19:09
Можно с помощью GetDIBits получить массив пикселей в нужном формате. По-идее, так гораздо быстрее должно быть.
1
 Аватар для Avaddon74
571 / 353 / 133
Регистрация: 15.09.2017
Сообщений: 1,239
26.07.2018, 22:46  [ТС]
Ygg, почитаю, по результатам отпишу
0
 Аватар для Avaddon74
571 / 353 / 133
Регистрация: 15.09.2017
Сообщений: 1,239
01.08.2018, 13:39  [ТС]
Ygg, Что-то я не могу в ней разобраться. Можете привести пример кода получения цвета пикселя с экрана? Заранее спасибо!
0
2735 / 890 / 331
Регистрация: 10.02.2018
Сообщений: 2,109
01.08.2018, 14:58
Лучший ответ Сообщение было отмечено Avaddon74 как решение

Решение

Как-то так:
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
#include <stdio.h>
#include <windows.h>
 
class CMyImage
{
public:
    char* bits;
    int linesize;
    int width;
    int height;
 
    CMyImage() : bits(0) {}
    ~CMyImage() { Clean(); }
 
    void Clean()
    {
        if (bits)
        {
            delete[] bits;
            bits = 0;
        };
    }
 
    void LoadFromScreen(int x, int y, int w, int h)
    {
        HDC screenDC = GetDC(0);
        HDC memDC = CreateCompatibleDC(screenDC);
        HBITMAP memBm = CreateCompatibleBitmap(screenDC, w, h);
        HBITMAP oldBm = (HBITMAP)SelectObject(memDC, memBm);
        BitBlt(memDC, 0, 0, w, h, screenDC, x, y, SRCCOPY);
 
        BITMAPINFOHEADER info;
        memset(&info, 0, sizeof(info));
        info.biSize = sizeof(BITMAPINFOHEADER);
        info.biCompression = BI_RGB;
        info.biPlanes = 1;
        info.biBitCount = 32;
        info.biWidth = w;
        info.biHeight = h;
        info.biSizeImage = h * ((w * info.biBitCount / 8 + 3) & ~3);
 
        width = w;
        height = h;
        linesize = (w * info.biBitCount / 8 + 3) & ~3;
        bits = new char[h * linesize];
 
        int checkMe = GetDIBits(memDC, memBm, 0, h, bits, (BITMAPINFO*)&info, 0);
 
        SelectObject(memDC, oldBm);
        DeleteObject(memBm);
        DeleteDC(memDC);
        ReleaseDC(0, screenDC);
    }
 
    void SaveToFile(const char* fileName)
    {
        if (!bits)
            return;
 
        BITMAPINFOHEADER imageHeader;
        memset(&imageHeader, 0, sizeof(imageHeader));
        imageHeader.biSize = sizeof(BITMAPINFOHEADER);
        imageHeader.biCompression = BI_RGB;
        imageHeader.biPlanes = 1;
        imageHeader.biBitCount = 32;
        imageHeader.biWidth = width;
        imageHeader.biHeight = height;
        imageHeader.biSizeImage = height * ((width * imageHeader.biBitCount / 8 + 3) & ~3);
 
        BITMAPFILEHEADER fileHeader;
        memset(&fileHeader, 0, sizeof(fileHeader));
        fileHeader.bfType = 'MB';
        fileHeader.bfOffBits = sizeof(fileHeader) + sizeof(imageHeader);
        fileHeader.bfSize = fileHeader.bfOffBits + imageHeader.biSizeImage;
 
        FILE* file = fopen(fileName, "wb");
        if (file)
        {
            fwrite(&fileHeader, sizeof(fileHeader), 1, file);
            fwrite(&imageHeader, sizeof(imageHeader), 1, file);
            fwrite(bits, imageHeader.biSizeImage, 1, file);
            fclose(file);
        }
    }
 
    unsigned GetPixel(int x, int y)
    {
        if (!bits || (x < 0) || (x >= width) || (y < 0) || (y >= height))
            return 0;
        return *(unsigned*)(bits + (height-y-1)*linesize + x * 4);
    }
 
    void printRGB(unsigned val)
    {
        printf("%02X:%02X:%02X", (val >> 16) & 255, (val >> 8) & 255, (val >> 0) & 255);
    }
};
 
int main()
{
    CMyImage image;
    image.LoadFromScreen(50, 50, 100, 100);
    image.SaveToFile("test.bmp");
 
    for (int y = 0; y < 5; y++)
    {
        for (int x = 0; x < 5; x++)
        {
            unsigned pix = image.GetPixel(x, y);
            image.printRGB(pix);
            printf(" ");
        }
        printf("\n");
    }
 
    getchar();
    return 0;
}
1
 Аватар для Avaddon74
571 / 353 / 133
Регистрация: 15.09.2017
Сообщений: 1,239
02.08.2018, 12:00  [ТС]
Ygg, Я что-то не пойму 90-ую строчку. Почему height-y-1, а не просто y картинка разве отраженная по вертикали?
и почему bits + (height-y-1)*linesize + x * 4) а не bits[(height-y-1)*linesize + x * 4)], ведь в первом варианте вернет адрес ячейки, а не содержимое?
По второму вопросу понял, упустил *(unsigned*)

Добавлено через 29 минут
И первый вопрос снимаю Убедился что отражена, остается вопрос почему отражена?
0
2735 / 890 / 331
Регистрация: 10.02.2018
Сообщений: 2,109
02.08.2018, 12:26
остается вопрос почему отражена?
Не знаю, так исторически сложилось. Из вики:
Usually pixels are stored "upside-down" with respect to normal image raster scan order, starting in the lower left corner, going from left to right, and then row by row from the bottom to the top of the image. Unless BITMAPCOREHEADER is used, uncompressed Windows bitmaps also can be stored from the top to bottom, when the Image Height value is negative.
1
 Аватар для Avaddon74
571 / 353 / 133
Регистрация: 15.09.2017
Сообщений: 1,239
02.08.2018, 15:11  [ТС]
Ygg, Спасибо, все таки код я лучше понимаю чем все описания функции в интернете ))
"Не надо больше слов, покажи мне код"
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
02.08.2018, 15:11
Помогаю со студенческими работами здесь

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

Способы получения ответов в VP 5.2
Здравствуйте, переношу экспертную из консольной в Визуал, но столкнулся в проблемой остановки предиката, чтобы получить ответ пользователя,...

Алгоритм получения значения RGB каждого пикселя картинки
Имеется произвольная цветная картинка на компе.Каким образом вытянуть из нее значения RGB каждого пикселя для последующей обработки на...

ServerSocket ClientSocket способы получения данных
Ранее написал в консольную програмку, передачи файлов на winsock2 при помощи send() и recv(), когда попытался реализовать это на C++...

Рандом - способы получения случайных чисел
Я умею пользоваться тремя стандартными способами получения случайных чисел: Math.random(), java.util.Random и java.security.SecureRandom. ...


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

Или воспользуйтесь поиском по форуму:
8
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Реализация движения на Box2D v3 - трение и коллизии с повёрнутыми стенами
8Observer8 20.02.2026
Содержание блога Box2D позволяет легко создать главного героя, который не проходит сквозь стены и перемещается с заданным трением о препятствия, которые можно располагать под углом, как верхнее. . .
Конвертировать закладки radiotray-ng в m3u-плейлист
damix 19.02.2026
Это можно сделать скриптом для PowerShell. Использование . \СonvertRadiotrayToM3U. ps1 <path_to_bookmarks. json> Рядом с файлом bookmarks. json появится файл bookmarks. m3u с результатом. # Check if. . .
Семь CDC на одном интерфейсе: 5 U[S]ARTов, 1 CAN и 1 SSI
Eddy_Em 18.02.2026
Постепенно допиливаю свою "многоинтерфейсную плату". Выглядит вот так: https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11617&stc=1&d=1771445347 Основана на STM32F303RBT6. На борту пять. . .
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
И ясному Солнцу
zbw 12.02.2026
И ясному Солнцу, и светлой Луне. В мире покоя нет и люди не могут жить в тишине. А жить им немного лет.
«Знание-Сила»
zbw 12.02.2026
«Знание-Сила» «Время-Деньги» «Деньги -Пуля»
SDL3 для Web (WebAssembly): Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 12.02.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами и вызывать обработчики событий столкновения. . . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 11.02.2026
Содержание блога Библиотека SDL3 содержит встроенные инструменты для базовой работы с изображениями - без использования библиотеки SDL3_image. Пошагово создадим проект для загрузки изображения. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru