Форум программистов, компьютерный форум, киберфорум
C/C++: WinAPI
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.69/29: Рейтинг темы: голосов - 29, средняя оценка - 4.69
 Аватар для SeaMonster
15 / 15 / 1
Регистрация: 31.12.2012
Сообщений: 101

Работа с отдельными пикселями

22.01.2013, 03:08. Показов 5955. Ответов 7
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Имеется область на hdc. Надо что-то с Каждым пикселем сделать и вернуть измененный пиксель назад или на другой hdc.
Я могу написать код по схеме - в двойном цикле берешь каждый пиксель, читаешь GetPixel , раскодируешь в цвета, что хочешь делаешь, записываешь назад или на другой SetPixel . Кое-что рабочее так уже написал, НО! попиксельная обработка такая, точнее Чтение и Запись - несравнимо медленнее стандартных функций.
Как можно лучше?
Скорее всего из указателя на hdc можно как-то "выдрать" где именно в памяти все лежит и "лезть" туда напрямую, но как именно?
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
22.01.2013, 03:08
Ответы с готовыми решениями:

Как работать с отдельными пикселями на изображении
Плиз помогите как работать с отдельными пикселями на изображении. Если точнее то я использую сетпиксель и гет пиксель, а при сохранении...

c# работа с пикселями.
бешеный проблема. Очень надо добить эту программу. Тут работа с изображениями, суть в том, что здесь я хочу запустить цикл по всем пикселям...

Работа с пикселями
1) Згенеруваты выпадкови дани що видповидають умови задачи и зберегты в текстовому редактори 2) Килькисть точок выбыраеться вид 10 до...

7
Неэпический
 Аватар для Croessmah
18146 / 10730 / 2066
Регистрация: 27.09.2012
Сообщений: 27,029
Записей в блоге: 1
22.01.2013, 06:18
Цитата Сообщение от SeaMonster Посмотреть сообщение
Скорее всего из указателя на hdc можно как-то "выдрать" где именно в памяти все лежит и "лезть" туда напрямую, но как именно?
Посмотрите в сторону DIB-секций
1
 Аватар для SeaMonster
15 / 15 / 1
Регистрация: 31.12.2012
Сообщений: 101
22.01.2013, 15:47  [ТС]
Вроде мощная вещь, но что неправильно в таком фрагменте кода?
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
BITMAPINFO bmi;
  ZeroMemory(&bmi, sizeof(BITMAPINFOHEADER));
 
  bmi.bmiHeader.biSize        = sizeof(BITMAPINFOHEADER);
  bmi.bmiHeader.biWidth       = 620;
  bmi.bmiHeader.biHeight      = 200;
  bmi.bmiHeader.biPlanes      = 1;
  bmi.bmiHeader.biCompression = BI_RGB;
  bmi.bmiHeader.biBitCount    = 32;
 
  DWORD *bitmapBits;
  HBITMAP bitmap = CreateDIBSection(txDC(), &bmi, DIB_RGB_COLORS, (void**)&bitmapBits, 0, 0);
Win32::SelectObject(txDC(), bitmap);
 
for (long int i1 = 0; i1<64000l; i1++){
 bitmapBits[i1] = RGB(140,2,1);
}
 
 
SetDIBitsToDevice(txDC(),0,0,320,200,0,0,  0,0,bitmapBits,&bmi,DIB_RGB_COLORS);

1. По идее то, что я написал - должно создать секцию на основе куска экрана, часть закрасить в один цвет, часть оставить как есть и снова вывести на экран.
2. На практике - создается секция заполненная нулями (черная), часть таки красится и так выводится.

Добавлено через 21 минуту
А в gdi+ есть высокоуровневые обертки для таких действий? Это же вроде gdi, так как потребовалась либа gdi32.dll чтобы откомпилить

Добавлено через 7 часов 10 минут
Попробовал создать достаточно серьезный пример
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<stdio.h>
#include<math.h>
#include<conio.h>
#include <gdiplus.h>
#include<Graphics.h>
 
 
#include<time.h>
int printtime(){int tit=clock () / CLOCKS_PER_SEC;printf("\n t=%d",tit);} /// В общем понятно. Мелкая функция для вывода на экран времени после старта программы
 
int drawBMP_xxx(const int x1,const int y1,const int dx,const int dy,const char* name,const int regim,const int zerkalo,const double arg1,const double arg2,const double arg3,const double arg4,const double arg5,const double arg6,const double arg7,const double arg8,const double arg9){
/// Аргументы функции
//// x1,y1 - начало куда рисовать
/// dx dy - желаемый размер картинки
/// regim режим. Есть 0 - ничего особого, 1 - перекраска пикселя по матрице преобразования цветов при помощи getpixel setpixel (работает но с тормозами) и 2 - попытка сделать тоже самое при помощи DBI (Пока абсолютно не работает)
/// zerkalo если ненулевое, то картинка будет "отражена в зеркале"
/// arg1  и далее - матрица перекодирования цвета. Разумеется в таком виде не очень удобно, но интерфейс позже, пока с Ядром проблемы....
wchar_t buffer4[1000];
double cf[3][3]={{arg1,arg2,arg3},{arg4,arg5,arg6},{arg7,arg8,arg9}}; /// Матрица аргументов для преобразования цветов
static HDC htest=txCreateCompatibleDC(1024,768); /// Один раз за программу статически создаем буферный hdc
 
for(int kk=0;kk<1000;kk++){buffer4[kk]=0;}
for(int i=0;i<1000;i++){
 int v=name[i];buffer4[i]=v;if(v==0){break;}
} /// Криво, но думаю надежно преобразуем простое имя файла в формат, который принимает конструктор объекта Gdiplus::Image
 
txBitBlt(htest,0,0,dx,dy,txDC(),x1,y1); //// Копируем ту область экрана, на которой надо нарисовать, в буфер
 
 
 
Gdiplus::Graphics graphics(htest); /// Создаем "рисовалку" gdi+ чтобы она рисовала в буфер
Gdiplus::Image* m_pImage=NULL;
m_pImage=new Gdiplus::Image(buffer4); /// Загружаем из файла картинку в объект gdi+
 
if(zerkalo){m_pImage->RotateFlip(Gdiplus::Rotate180FlipY );}  /// Если задано зеркало - при помощи собственной функции gdi+ отражаем в зеркале
 
 
Gdiplus::Rect rc(0,0,dx,dy); ///Прямоугольник куда рисовать. Рисуем в начало буфера по выбранным размерам
graphics.DrawImage(                m_pImage,                        // [in] Gdiplus::Image object
     rc                                // [in] Position and dimensions
     );  //////// Рисуем загруженную картинку gdi+ в буферный hdc
if(regim==0){} /// В нулевом режиме ничего не делаем, картинка уже какая надо.
 
 
if(regim==1){
 for(int i=0;i<dx;i++){for(int j=0;j<dy;j++){
  COLORREF c_buf=Win32::GetPixel(htest,i,j);
 int r =(BYTE)(c_buf>>0);
int g = (BYTE)(c_buf>>8);
int    b = (BYTE)(c_buf>>16);
Win32::SetPixel(htest,i,j,RGB(cf[0][0]*r+cf[0][1]*g+cf[0][2]*b,cf[1][0]*r+cf[1][1]*g+cf[1][2]*b,cf[2][0]*r+cf[2][1]*g+cf[2][2]*b));
 
/// При помощи примитивной попиксельной работы с GetPixel получаем цвет каждого пикселя, раскодирывем его , преобразуем по матрице и снова рисуем.
 
}}
}
 
 
if(regim==2){
///// Пробуем работать с DIBSextion  ПОКА НЕ РАБОТАЕТ!!!
BITMAPINFO bmi;
 ZeroMemory(&bmi, sizeof(BITMAPINFOHEADER));
 
  bmi.bmiHeader.biSize        = sizeof(BITMAPINFOHEADER);
  bmi.bmiHeader.biWidth       = dx;
  bmi.bmiHeader.biHeight      = -dy;
  bmi.bmiHeader.biPlanes      = 1;
  bmi.bmiHeader.biCompression = BI_RGB;
  bmi.bmiHeader.biBitCount    = 32;
 
  DWORD *bitmapBits;
  HBITMAP bitmap = CreateDIBSection(htest, &bmi, DIB_RGB_COLORS, (void**)&bitmapBits, 0, 0);
Win32::SelectObject(htest, bitmap);
/* Пока ничего не делаем, по идее должна создаваться секция на основе htest и снова рисоваться на htest , то есть внешне ничего не происходить. Но создается секция заполненная нулями!
for (long int i1 = 0; i1<64000l; i1++){
///// bitmapBits[i1] = RGB(140,2,1);
}*/
 
 
SetDIBitsToDevice(htest,0,0,dx,dy,0,0,  0,0,bitmapBits,&bmi,DIB_RGB_COLORS);
 
 
 
}
 
 
txBitBlt(txDC(),x1,y1,dx,dy,htest,0,0); /// выводим выведенную в буфер и обработанную картинку окончательно на экран
delete(m_pImage); /// не мусорим gdi+ объектами, культурно удаляем
}
 
 
 
 
 
 
 
 
 
 
 
 
int main(){
 
int gd,gm;
initgraph(&gd,&gm,""); /// Извратная инициализация полноэкранной графики
 
{
{
Gdiplus::GdiplusStartupInput gdiplusStartupInput; 
ULONG_PTR gdiplusToken; 
GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
} //// Инициализация gdi+
 
 
}
 
cleardevice();
 
for(int k=0;k<50;k++){
 
drawBMP_xxx(100,0,676,600,"Tigre039.jpg",1,0, 0,0,0 ,0.5,0.5,0.5, 0.5,0.5,0.5); /// Красим картинку в циан
drawBMP_xxx(800,0,676,600,"Tigre039.jpg",1,1, 0.33,0.33,0.33, 0.33,0.33,0.33, 0.33,0.33,0.33); //// Просто в черно-белый
printf("\n k=%d",k);printtime(); ////Показываем на экране сколько раз уже вывелось и время прошедшее с начала запуска программы
 
/////Выводим картинки много раз циклом для тестирования времени работы
}
 
getch();
 
 
 
}
Если написать именно как в примере - то все задекларированное в main работает как надо, но Большие Тормоза.
Если функциям приписать режим 0 (без обработки) то все летает, но картинки исходного цвета
Если режим 2 - то по идее должны быть исходные картинки, но на практике - черные области....
0
8 / 8 / 1
Регистрация: 11.08.2012
Сообщений: 112
22.01.2013, 18:24
Если интересно, в соседней теме только что запустил программу, для получения скриншота рабочего стола при помощи directX. Собственно полученную поверхность можно не сохранять в качестве .bmp файла, а крутить как вам заблагорассудится (примеры есть в посте выше, той же темы)
1
 Аватар для SeaMonster
15 / 15 / 1
Регистрация: 31.12.2012
Сообщений: 101
22.01.2013, 19:19  [ТС]
Спасибо. Но у меня мой MinGW почему-то не знает библиотеку #include <d3dx9tex.h> (#include <d3d9.h> нормально принял). Что делать?
0
8 / 8 / 1
Регистрация: 11.08.2012
Сообщений: 112
22.01.2013, 19:28
Цитата Сообщение от SeaMonster Посмотреть сообщение
Спасибо. Но у меня мой MinGW почему-то не знает библиотеку #include <d3dx9tex.h> (#include <d3d9.h> нормально принял). Что делать?
Хм.... d3dx9tex.h отвечает за работу D3DXSaveSurfaceToFile() т.е. за сохранение поверхности в .bmp файл, если эта функция не нужна - то ее можно выбросить, и библиотеку не юзать (сам использовал только для проверки работоспособности). У меня VS2010, библиотек d3d вообще не было, качал откуда то со стороннего источника (возможно есть даже на сайте майкрософта).
1
 Аватар для SeaMonster
15 / 15 / 1
Регистрация: 31.12.2012
Сообщений: 101
22.01.2013, 19:53  [ТС]
Хорошо, буду дальше разбираться

Добавлено через 6 минут
Гм. Осталась только одна ошибка Компиляции. Компилятор не знает GetConsoleWindow(); хотя вроде это из элементарной windows.h
0
8 / 8 / 1
Регистрация: 11.08.2012
Сообщений: 112
23.01.2013, 17:39
Цитата Сообщение от SeaMonster Посмотреть сообщение
Хорошо, буду дальше разбираться

Добавлено через 6 минут
Гм. Осталась только одна ошибка Компиляции. Компилятор не знает GetConsoleWindow(); хотя вроде это из элементарной windows.h
В принципе прога работает и без GetConsoleWindow(), главное дать CreateDevice переменную типа HWND (насколько я понял, дескриптор окна нужен для вывода графики, а тут ничего выводить не надо, да и в консоль ее не вывести по определению )

Добавлено через 21 час 12 минут
Программа создает скриншот рабочего стола, редактирует его (в данном примере все закрашивается красным цветом) а потом сохраняет его в файл.

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
#include <iostream>
#include <stdio.h>
#include <Windows.h>
#include <d3d9.h>
#include <d3dx9tex.h>
 
#pragma comment(lib,"d3dx9.lib")
#pragma comment(lib,"d3d9.lib")
 
 
int main()
{
    IDirect3D9 *g_pD3D;
    HWND hWnd;
    
    IDirect3DDevice9 *g_pd3dDevice;
    IDirect3DSurface9 *pSurface;
    D3DDISPLAYMODE d3ddm;
    D3DPRESENT_PARAMETERS d3dpp;
    D3DSURFACE_DESC surfaceDesc;
    D3DLOCKED_RECT lockedRect;
 
    hWnd = GetConsoleWindow();
 
    if((g_pD3D = Direct3DCreate9(D3D_SDK_VERSION)) == NULL) {
     printf("fail 1");
    }
    if(FAILED(g_pD3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &d3ddm))) {
    printf("fail 2");
    }
    ZeroMemory(&d3dpp, sizeof(D3DPRESENT_PARAMETERS));
 
    d3dpp.Windowed = TRUE;
    d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
    d3dpp.BackBufferFormat = d3ddm.Format;
    d3dpp.BackBufferHeight = d3ddm.Height;
    d3dpp.BackBufferWidth = d3ddm.Width;
 
 
    if(FAILED(g_pD3D->CreateDevice(D3DADAPTER_DEFAULT,
                               D3DDEVTYPE_HAL, hWnd,
                               D3DCREATE_SOFTWARE_VERTEXPROCESSING,
                               &d3dpp, &g_pd3dDevice))) {
    printf("fail 3");
    }
    
    if(FAILED(g_pd3dDevice->CreateOffscreenPlainSurface(d3ddm.Width, d3ddm.Height,
        D3DFMT_A8R8G8B8, D3DPOOL_SCRATCH, &pSurface, NULL)))
    {
        printf("fail 4");
    }
    ///////////////////////////////////////////////////////////////////////////////////////
    g_pd3dDevice->GetFrontBufferData(0, pSurface);
    pSurface->GetDesc(&surfaceDesc);
    pSurface->LockRect(&lockedRect, 0, 0);
 
    DWORD* imageData = (DWORD*)lockedRect.pBits;
 
    for(int i = 0; i < surfaceDesc.Height; i++)
    {
        for(int j = 0; j < surfaceDesc.Width; j++)
        {
        // индекс в текстуре, обратите внимание, что мы используем шаг и
        // делим его на 4, поскольку шаг задается в байтах,
        // а каждый пиксель занимает 4 байта.
            int index = i * lockedRect.Pitch / 4 + j;
            imageData[index] = 0xffff0000; // красный цвет
        }
    }
 
    pSurface->UnlockRect();
    ///////////////////////////////////////////////////////////////////////////////////////
    D3DXSaveSurfaceToFile(L"Desktop.bmp",D3DXIFF_BMP,pSurface,NULL,NULL);
    pSurface->Release(); 
 
    return 0;
}
Считается что видеорежим 32 бита (888+альфа)
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
23.01.2013, 17:39
Помогаю со студенческими работами здесь

Работа с пикселями
загружаю рисунок в pictureBox, беру например пиксель по координатам 10, 10 . А вот как его изменить никак не пойму. Делаю так: ...

Работа с пикселями в C#
Здравствуйте. Имеется приложение на C#, которое берет изображение с веб-камеры в PictureBox. На форму поставил компонент ListView, в...

Работа с пикселями
Возможно ли работать с пикселями в С++? Сравнение цветов пикселей требуется Добавлено через 2 минуты Кратко суть программы: ...

Работа с пикселями
Я только осваиваюсь с графикой, но пока ниче не получается...Если Вам не трудно, то помогите с этой задачей: Общее условие:...

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


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

Или воспользуйтесь поиском по форуму:
8
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Работа со звуком через SDL3_mixer
8Observer8 08.02.2026
Содержание блога Пошагово создадим проект для загрузки звукового файла и воспроизведения звука с помощью библиотеки SDL3_mixer. Звук будет воспроизводиться по клику мышки по холсту на Desktop и по. . .
SDL3 для Web (WebAssembly): Основы отладки веб-приложений на SDL3 по USB и Wi-Fi, запущенных в браузере мобильных устройств
8Observer8 07.02.2026
Содержание блога Браузер Chrome имеет средства для отладки мобильных веб-приложений по USB. В этой пошаговой инструкции ограничимся работой с консолью. Вывод в консоль - это часть процесса. . .
SDL3 для Web (WebAssembly): Обработчик клика мыши в браузере ПК и касания экрана в браузере на мобильном устройстве
8Observer8 02.02.2026
Содержание блога Для начала пошагово создадим рабочий пример для подготовки к экспериментам в браузере ПК и в браузере мобильного устройства. Потом напишем обработчик клика мыши и обработчик. . .
Философия технологии
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 была полностью переписана на Си, в. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru