Форум программистов, компьютерный форум, киберфорум
C/C++: WinAPI
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.94/18: Рейтинг темы: голосов - 18, средняя оценка - 4.94
7 / 7 / 2
Регистрация: 24.02.2013
Сообщений: 90

GetPixel(), BitMap()

11.11.2017, 16:50. Показов 3910. Ответов 10
Метки нет (Все метки)

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

Столкнулся с проблемой, что "GetPixel()" работает медленно на Windows 7 и выше, если стоит стиль оформления "Aero". Покопался на форуме и нашел отличную тему, где человек выложил свою версию "GetPixel()". В ней есть привязка к конкретному окну и работает она гораздо быстрее, но есть две проблемы:

1) При получении цвета пикселя, Red и Blue меняются местами. Но это проблема легко решаема, поэтому она меня не интересует.
2) Описать эту проблему легче скриншотом, чем словами:


Здесь я брал координаты цвета пикселя из окна "CodeBlocks" и отрисовывал его. Проблема в том, что до какого-то определенного момента цвет пикселя определяется нормально, а потом что-то происходит (не знаю что) и функция перестает нормально работать (черные полосы).

Сначала подумал, что память забивается из-за очень частого использования, но по идее, она очищается функцией "ReleaseDC", поэтому такой вариант я откинул. А больше вариантов у меня и нет.

Из-за чего это может происходить? Помогите, пожалуйста, решить данную проблему.

Выкладываю код этой самодельной функции "GetPixel":

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
double MyGetPixel(HWND hGame,int x,int y)  
{
        COLORREF pixel;
        BITMAPINFO BMI={0};
        HDC hGDC = GetDC(hGame);
        int Bitp=GetDeviceCaps(hGDC, BITSPIXEL);
        HDC hTmpDC=CreateCompatibleDC(hGDC);
        HBITMAP hTmpBmp=CreateCompatibleBitmap(hGDC,1,1);
        SelectObject(hTmpDC,hTmpBmp);
        BitBlt(hTmpDC,0,0,1,1,hGDC,x,y,SRCCOPY);
        BMI.bmiHeader.biSize = sizeof(BMI.bmiHeader);
        BMI.bmiHeader.biWidth = 1;
        BMI.bmiHeader.biHeight = 1;
        BMI.bmiHeader.biPlanes = 1;
        BMI.bmiHeader.biBitCount = Bitp;
        BMI.bmiHeader.biCompression = BI_RGB;
        BMI.bmiHeader.biSizeImage=Bitp/8;
        BMI.bmiHeader.biClrUsed = 0;
        BMI.bmiHeader.biClrImportant = 0;
        int TMP=GetDIBits(hTmpDC,hTmpBmp,0,1,&pixel,&BMI, DIB_RGB_COLORS);
        pixel&=0xFFFFFF;
        ReleaseDC(hGame,hGDC);
        pixel = RGB(GetBValue(pixel), GetGValue(pixel), GetRValue(pixel));
        pixel = (double) pixel;
        return pixel;
}
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
11.11.2017, 16:50
Ответы с готовыми решениями:

Получение фото с веб камеры, занесение его в Bitmap и преобразование Bitmap в массив
В общем необходимо подключиться к веб камере сделать снимок и отправить его в сеть. Задачу я разделил на несколько этапов. 1. Сам...

GetPixel
#include <iostream> #include <windows.h> #include <stdlib.h> #include <tchar.h> using namespace std; int _tmain(int argc,...

GetPixel() и SetWindowText()
Здравствуйте. Например во Flash и Javascript есть инструменты(функции) для отладки(trace(),console.log()) где можно увидеть значение...

10
1130 / 789 / 232
Регистрация: 12.04.2010
Сообщений: 2,012
11.11.2017, 20:33
Цитата Сообщение от zzzzza Посмотреть сообщение
Сначала подумал, что память забивается из-за очень частого использования
zzzzza, наверное сначала Вы были правы. Вот что написано в msdn.

CreateCompatibleDC
Remarks. When you no longer need the memory DC, call the DeleteDC function.
CreateCompatibleBitmap
Remarks. When you no longer need the bitmap, call the DeleteObject function to delete it.
Об этом же говорят участники в указанной Вами теме

Добавлено через 4 минуты
Цитата Сообщение от zzzzza Посмотреть сообщение
pixel = RGB(GetBValue(pixel), GetGValue(pixel), GetRValue(pixel));
Первый параметр макроса RGB - это red.

RGB ( red, green, blue )
1
7 / 7 / 2
Регистрация: 24.02.2013
Сообщений: 90
12.11.2017, 05:26  [ТС]
Alex5, спасибо, попробую. Думаю, что поможет. Отпишусь, как попробую.
А насчет
C++
1
pixel = RGB(GetBValue(pixel), GetGValue(pixel), GetRValue(pixel));
Тут все правильно, так как почему-то синий и красный меняются местами во время всех операций, а эта строчка меняет их местами, чтобы получился правильный цвет.

Добавлено через 1 час 39 минут
Добавил "DeleteDC" и "DeleteObject" и ничего не изменилось. Вообще ничего!

Вот код:
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
double MyGetPixel(HWND hGame,int x,int y)  
{
        COLORREF pixel;
        BITMAPINFO BMI={0};
        HDC hGDC = GetDC(hGame);
        int Bitp=GetDeviceCaps(hGDC, BITSPIXEL);
        HDC hTmpDC=CreateCompatibleDC(hGDC);
        HBITMAP hTmpBmp=CreateCompatibleBitmap(hGDC,1,1);
        SelectObject(hTmpDC,hTmpBmp);
        BitBlt(hTmpDC,0,0,1,1,hGDC,x,y,SRCCOPY);
        BMI.bmiHeader.biSize = sizeof(BMI.bmiHeader);
        BMI.bmiHeader.biWidth = 1;
        BMI.bmiHeader.biHeight = 1;
        BMI.bmiHeader.biPlanes = 1;
        BMI.bmiHeader.biBitCount = Bitp;
        BMI.bmiHeader.biCompression = BI_RGB;
        BMI.bmiHeader.biSizeImage=Bitp/8;
        BMI.bmiHeader.biClrUsed = 0;
        BMI.bmiHeader.biClrImportant = 0;
        int TMP=GetDIBits(hTmpDC,hTmpBmp,0,1,&pixel,&BMI, DIB_RGB_COLORS);
        pixel&=0xFFFFFF;
        ReleaseDC(hGame,hGDC);
        
        DeleteObject(hTmpBmp);
        DeleteDC(hTmpDC);
 
        pixel = RGB(GetBValue(pixel), GetGValue(pixel), GetRValue(pixel));
        pixel = (double) pixel;
        return pixel;
}
0
1130 / 789 / 232
Регистрация: 12.04.2010
Сообщений: 2,012
12.11.2017, 13:13
Цитата Сообщение от zzzzza Посмотреть сообщение
Добавил "DeleteDC" и "DeleteObject" и ничего не изменилось.
Может быть, есть другие причины. Как происходит рисование, может быть там какие-то объекты не удаляются?

Как будет работать такая версия? Не случится ли, что и здесь будут возникать черные полосы?
C++
1
2
3
4
double MyGetPixel(HWND hGame,int x,int y)  
{
    return  (double) 255;   
}
1
1130 / 789 / 232
Регистрация: 12.04.2010
Сообщений: 2,012
12.11.2017, 13:43
Добавим в MyGetPixel из сообщения 1 :
C++
1
2
3
4
5
6
7
8
 
    HDC hTmpDC=CreateCompatibleDC(hGDC);
    if( ! hTmpDC) 
        throw -1;
        
    HBITMAP hTmpBmp=CreateCompatibleBitmap(hGDC,1,1);
    if( ! hTmpBmp) 
        throw -2;
При отсутствии DeleteObject, DeleteDC , в цикле возникает исключение примерно на шаге 4900.
После добавления DeleteObject, DeleteDC исключений в MyGetPixel не возникает.
Миниатюры
GetPixel(), BitMap()  
1
Фриланс Pascal/Delphi etc
 Аватар для ILinker
67 / 73 / 16
Регистрация: 25.11.2016
Сообщений: 263
12.11.2017, 15:47
Попробуйте CreateDIBSection() использовать или получать GetPixel() для hTmpDC.
0
7 / 7 / 2
Регистрация: 24.02.2013
Сообщений: 90
12.11.2017, 16:19  [ТС]
Alex5, и правда проблема была в рисование, сам код работает хорошо. Даже не думал об этом, спасибо огромное!!
0
 Аватар для Alikberov
131 / 116 / 25
Регистрация: 03.05.2017
Сообщений: 337
Записей в блоге: 1
12.11.2017, 22:41
Думaю, эти строчку нужно поменять местами:
C++
1
2
        DeleteObject(hTmpBmp);
        DeleteDC(hTmpDC);
Где-то читал тоже, что выбранный контексту объект удалять - не хорошо. Или выбираем «фондовый» (GetStockObject) перед удалением:
C++
1
2
        DeleteObject(SelectObject(hTmpBmp, GetStockObject(HOLLOW_BRUSH));
        DeleteDC(hTmpDC);
или контекст - первым:
C++
1
2
        DeleteDC(hTmpDC);
        DeleteObject(hTmpBmp);
1
7 / 7 / 2
Регистрация: 24.02.2013
Сообщений: 90
13.11.2017, 22:22  [ТС]
Alikberov, исправлю. Спасибо!

Добавлено через 21 час 29 минут
Решил оптимизировать этот код и дошел до этого момента:
C++
1
2
3
4
5
6
7
8
9
10
COLORREF MyGetPixel(HWND hWnd,int x,int y)  
{
  HDC hGDC = GetDC(hWnd);
  HDC hTmpDC=CreateCompatibleDC(hGDC);
  HBITMAP hTmpBmp=CreateCompatibleBitmap(hGDC,1,1);
  SelectObject(hTmpDC,hTmpBmp);
  BitBlt(hTmpDC,0,0,1,1,hGDC,x,y,SRCCOPY);
  BITMAP map;
  GetObject(hTmpBmp, sizeof(BITMAP), &map);
}
Теперь в map лежат все пиксели (в нашем случае один).

Как достать оттуда цвет пикселя?

Весь день просидел, понял, что надо использовать:
C++
1
2
3
BYTE bpp=map.bmBitsPixel>>3;
BYTE *pbits=new BYTE[map.bmWidth*map.bmHeight*bpp];
pixel=*(DWORD*) pbits<<(32-map.bmBitsPixel);
Но ничего не работает.
1
Фриланс Pascal/Delphi etc
 Аватар для ILinker
67 / 73 / 16
Регистрация: 25.11.2016
Сообщений: 263
15.11.2017, 13:14
Как-то так?

Delphi
1
Data.bmBitsPixel[(X * Data .bmWidth + Y) * 4])
1
7 / 7 / 2
Регистрация: 24.02.2013
Сообщений: 90
15.11.2017, 16:31  [ТС]
ILinker, спасибо! Уже разобрался.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
15.11.2017, 16:31
Помогаю со студенческими работами здесь

GetPixel() работает нереально медленно на Windows 7
Написал программу (бот для онлайн игры), вся его работа заключается в получении цвета пикселя в нужных координатах и совершения тех или...

GetPixel неправильно определяет цвет пикселя
Господа такая ситуация - я нарисовал в своём окне линию красного цвета , затем при помощи GetPixel пытаюсь определить какого цвета пиксел ,...

Функция GetPixel, не понимаю систему координат
Есть код который определяет в окне линию определенного цвета но я не могу понять саму систему координат кто поможет? Добавлено через 2...

Что передавать в качестве параметра hdc функции "GetPixel"
А именно: COLORREF GetPixel( _In_ HDC hdc, _In_ int nXPos, _In_ int nYPos ); Что писать в hdc?

BITMAP
Здравствуйте. Возникла проблема. Мне надо вставить изображение в клиентскую область окна. Использую функцию LoadImage. Но что то пока...


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

Или воспользуйтесь поиском по форуму:
11
Ответ Создать тему
Новые блоги и статьи
http://iceja.net/ математические сервисы
iceja 20.01.2026
Обновила свой сайт http:/ / iceja. net/ , приделала Fast Fourier Transform экстраполяцию сигналов. Однако предсказывает далеко не каждый сигнал (см ограничения http:/ / iceja. net/ fourier/ docs ). Также. . .
http://iceja.net/ сервер решения полиномов
iceja 18.01.2026
Выкатила http:/ / iceja. net/ сервер решения полиномов (находит действительные корни полиномов методом Штурма). На сайте документация по API, но скажу прямо VPS слабенький и 200 000 полиномов. . .
Расчёт переходных процессов в цепи постоянного тока
igorrr37 16.01.2026
/ * Дана цепь постоянного тока с R, L, C, k(ключ), U, E, J. Программа составляет систему уравнений по 1 и 2 законам Кирхгофа, решает её и находит переходные токи и напряжения на элементах схемы. . . .
Восстановить юзерскрипты Greasemonkey из бэкапа браузера
damix 15.01.2026
Если восстановить из бэкапа профиль Firefox после переустановки винды, то список юзерскриптов в Greasemonkey будет пустым. Но восстановить их можно так. Для этого понадобится консольная утилита. . .
Сукцессия микоризы: основная теория в виде двух уравнений.
anaschu 11.01.2026
https:/ / rutube. ru/ video/ 7a537f578d808e67a3c6fd818a44a5c4/
WordPad для Windows 11
Jel 10.01.2026
WordPad для Windows 11 — это приложение, которое восстанавливает классический текстовый редактор WordPad в операционной системе Windows 11. После того как Microsoft исключила WordPad из. . .
Classic Notepad for Windows 11
Jel 10.01.2026
Old Classic Notepad for Windows 11 Приложение для Windows 11, позволяющее пользователям вернуть классическую версию текстового редактора «Блокнот» из Windows 10. Программа предоставляет более. . .
Почему дизайн решает?
Neotwalker 09.01.2026
В современном мире, где конкуренция за внимание потребителя достигла пика, дизайн становится мощным инструментом для успеха бренда. Это не просто красивый внешний вид продукта или сайта — это. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru