gIReadBuffer - выбор буфера цвета для чтения. gIReadPixels - чтение данных из указанного буфера.
/*
Демонстрация работы с буфером цвета.
В качестве тестового изображения используется фрактал.
*/
Fractalset fs; // объект построения фрактала IMAGE img; // изображение
// переменные для изменения вида фрактала float step=60; float Cdelta=0.01; complexf С;
// переменные для генерации новой палитры int poffset=0; int pshift=0;
void example_init()
{
gl.set(1);
// строим фрактал множество Жюлиа C=fs.с;
fs.setJ(complex_f); img.init(); // инициализируем изображение // генерируем палитру randomize(); float pal[2048];
//заполняем палитру for(int i=0;i<256;i++) pal[i]=(float)i/256.0; copy(pal,pal + 7 68,pal+256) ; copy(pal,pal+256,pal + 1280) ; copy(pal,pal + 256,pal + 1792) ;
// устанавливаем палитру glPixelMapfv(GL_PIXEL_MAP_I_TO_R, 2048, pal) ; glPixelMapfv(GL_PIXEL_MAP_I_TO_G, 1024 , pal + 256) ; glPixelMapfv(GL_PIXEL_MAP_I_TO_B,512,pal+1280);
}
void example_deinit()
{
gl.deinit () ;
// сохраняем последнее изображение фрактала
img.savebmp("fractal.bmp");
}
// обработка ввода
void input()
{
int k=in.vkey; in.vkey=0;
if (k)
{
switch(k)
{
// перемещаем фрактал case VK_LEFT: fs.move(step,0,1); break; case VK_RIGHT: fs.move(-step,0,1); break; case VK_UP: fs.move(0,-step,1); break; case VK_DOWN: fs.move(0,step,1); break;
// масштабируем фрактал case VK_ADD: fs.move(0,0,2); break; case VK_SUBTRACT: fs.move(0,0,0.5); break // изменяем фрактал
case ’Q': C+=Cdelta; break; case 'A': C-=Cdelta; break; case 'Z': C*=-l; break; case 'W': Cdelta*=10; break; case 'S': Cdelta/=10; break; case 'E':
C=complexf(C.real(),C.imag()+Cdelta);
break; case 'D':
C=complexf(C.real(),C.imag()-Cdelta); break; case 1 С':
C=complexf(C.real(),-C.imag()); break;
// генерируем новую палитру case 'O': poffset+=5; return; case 'P': poffset-=5; return; case 'K': poffset+=256; return; case 'L': poffset-=256; return;
case 'R1: pshift++; return; case 'T': pshift--; return;
/*
Сохраняем фрактал в img как 24-битное изображение. Сохранение будет корректным, если zoomx=zoomy=l.
*/
case VK_F1: img.fromcolor(320,200); return;
// возвращаем палитру и позицию // фрактала в прежнее состояние default: pshift=l; poffset=0; fs.init ();
}
// строим фрактал заново fs.c=C;
fs.setJ(complex_f);
}
}
void draw() // вывод сцены
{
input();
glClear(GL_COLOR_BUFFER_BIT) ;
// изменяем правило пересылки пикселей glPixelTransferi(GL_INDEX_OFFSET,poffset); glPixelTransferi(GL_INDEX_SHIFT,pshift);
// устанавливаем растровую позицию glRasterPos2i(0,0);
// выводим фрактал как 8-битное изображение glDrawPixels(fs.w,fs.h,GL_COLOR_INDEX,
GL_UNSIGNED_BYTE,fs.data) ;
}
Обработка изображений
В общем, обработка готового изображения сводится к последовательному применению различных эффектов. При этом преобразования, происходящие над содержимым изображения, довольно просты для понимания. Например, применяя к компонентам цвета каждого пикселя обычные математические операции, можно добиться различных эффектов.
Вышеперечисленные эффекты, за исключением последнего, являются частным случаем общего алгоритма преобразования изображения, известного как фильтрация. Возьмем некоторую квадратную матрицу фильтра с нечетным числом элементов и наложим, например, на красный канал так, чтобы центр матрицы совпал с обрабатываемым пикселем.