Отобразить массив цветов в C

Моя программа пишет как чтение массивов цветов, подобных этой:

struct Image { size_t width; size_t height; struct Color *data; } struct Color { char r; char g; char b; } 

Как я могу отобразить такой массив на экране в C?

    Графическая визуализация:

    Я привык к win32 и Borland C ++, поэтому я придерживаюсь этого, но различия в других средах в основном относятся только к именам classов. Сначала некоторые подходы:

    1. консольные / текстовые режимы

      вы можете использовать текстовую графику ( искусство ASCII, я думаю, на английском языке). Где точка представлена символом . Интенсивность производится более или менее заполненными символами. Обычно есть таблица символов, отсортированная по интенсивности, например " ..:+*#" и используйте это вместо цветов. Для распечатки что-то может использовать iostream как cout << "text" << endl; или printf из stdio Я думаю (не используя старую консольную версию более десяти лет).

      Текстовые режимы videoram ( VRAM ) начинаются с 0B000:0000 если у вас есть привилегии для этого, вы можете сделать прямой доступ следующим образом:

       char far *scr=(char far*)0x0B0000000; scr[0]='A'; // print A to left upper corner 

      но в Windows вы можете забыть о прямом доступе

    2. Режим VGA gfx

      на Windows вы также можете забыть об этом ... Вот небольшой пример:

        //============================================================================== char far* scr; // VGA screen const _sx= 320; // physical screen size const _sy= 200; //============================================================================== void gfxinit(); void cls(); void pnt(int x,int y,char c); //============================================================================== void gfxinit() { asm { mov ax,19 // this swith VGA to 320*200*256 color mode (fits inside single 64KB segment so no funny stuff is needed) int 16 } for (int i=0;i<256;i++) asm { // this overwrites 256 color palette with some BW gradients mov dx,0x3C8 mov ax,i out dx,al // overwrite color al = i inc dx shr al,2 // al=al>>2 out dx,al // r,g,b or b,g,r not sure now out dx,al // all values are 6bit long therefore the shr al,2 out dx,al } scr=(char far*)0xA0000000; // VRAM start address } //============================================================================== void cls() // this clear screen with zero { asm { push es mov ax,0xA000 mov es,ax mov di,0x0000 sub ax,ax mov cx,32000 rep stosw pop es } } //============================================================================== void pnt(int x,int y,char c) // this draw single point of color c { unsigned int adr; if (x<_sx) if (x>=0) if (y<_sy) if (y>=0) { y=y*_sx; adr=x+y; scr[adr]=c; } } //============================================================================== 

      Доступ VESA аналогичен, но вам приходится иметь дело с пересечением сегментов и поисковым вызовом. Здесь небольшой пример Turbo C ++:

      VESA.h

       //============================================================================== //=== Globals: ================================================================= //============================================================================== char far* scr=(char far*)0xA0000000; // VGA/VESA memory pointer int VESA_page,VESA_pages; // actaul page and total pages int VESA_xs,VESA_ys,VESA_bpp; // video mode properties int VESA_page_xy[64]={-1,-1}; // starting x,y for each page const int VESAmodes[]= // usable video modes table { 320, 200, 8,0x150, 640, 480, 8,0x101, 800, 600, 8,0x103, 1024, 768, 8,0x105, 1280,1024, 8,0x107, 320, 200,16,0x10E, 640, 480,16,0x111, 800, 600,16,0x114, 1024, 768,16,0x117, 320, 200,32,0x10F, 640, 480,32,0x112, 800, 600,32,0x115, 0,0,0,0 }; //============================================================================== //=== Headers: ================================================================= //============================================================================== int VESAmode(int xs,int ys,int bpp); // set video mode void VESApage(int page); // set page void VESAexit(); // return to VGA text mode void VESAcls(); // clear with 0 void VESApnt(int x,int y,unsigned int c); // render 8/16 bpp point void VESApnt32(int x,int y,int r,int g ,int b); // render 32bpp point //============================================================================== //=== Graphic: ================================================================= //============================================================================== int VESAmode(int xs,int ys,int bpp) { int i,mode,x,y; unsigned int adr0,adr,dx,dy; // find video mode for (i=0;VESAmodes[i];i+=4) if (VESAmodes[i+0]==xs) if (VESAmodes[i+1]==ys) if (VESAmodes[i+2]==bpp) break; if (!VESAmodes[i]) return 0; mode=VESAmodes[i+3]; VESA_xs=xs; VESA_ys=ys; VESA_bpp=bpp; // compute start x,y for each page>0 dx=bpp>>3; dy=xs*dx; VESA_pages=1; for (adr=i=x=y=0;yadr) { while (adr>0) { adr-=dx; x--; } while (x<0) { x+=VESA_xs; y--; } VESA_page_xy[i]=x; i++; VESA_page_xy[i]=y+1; i++; VESA_pages++; } } VESA_page_xy[i]=-1; i++; VESA_page_xy[i]=-1; i++; // set vide mode asm { mov bx,mode mov ax,0x4F02 int 16 } VESApage(0); /* // set palette to grayscale if (VESAbpp==8) for (int i=0;i<256;i++) asm { mov dx,0x3C8 mov ax,i out dx,al inc dx shr al,2 out dx,al out dx,al out dx,al } */ return 1; } //============================================================================== void VESApage(int page) { int p=page; asm { mov dx,p mov bx,0 mov ax,0x4f05 int 16 } VESA_page=page; } //============================================================================== void VESAexit() { asm { // waut for key press mov ax,0 int 0x16 // VGA 80x25 text mode mov ax,3 int 16 } } //============================================================================== void VESAcls() { int i; for (i=0;i=0)&&(x=0)&&(y>3); // page for (p=0;VESA_page_xy[p+p+0]>=0;p++) { if (VESA_page_xy[p+p+1]>y) break; if (VESA_page_xy[p+p+1]x) break; } if (p!=VESA_page) VESApage(p); // render scr[adr]=c; if (VESA_bpp==16) { adr++; if (adr==0) VESApage(p+1); scr[adr]=(c>>8); } } } //============================================================================== void VESApnt32(int x,int y,int r,int g ,int b) { unsigned int adr; int p; // inside screen? if ((x>=0)&&(x=0)&&(y>3); // page for (p=0;VESA_page_xy[p+p+0]>=0;p++) { if (VESA_page_xy[p+p+1]>y) break; if (VESA_page_xy[p+p+1]x) break; } if (p!=VESA_page) VESApage(p); // render scr[adr]=b; adr++; if (adr==0) VESApage(p+1); scr[adr]=g; adr++; if (adr==0) VESApage(p+1); scr[adr]=r; } } //============================================================================== //=== End. ===================================================================== //============================================================================== 

      main.cpp

       //============================================================================== //=== Includes: ================================================================ //============================================================================== #include "vesa.h" //============================================================================== //=== Main: ==================================================================== //============================================================================== void main() { if (!VESAmode(800,600,32)) return; VESAcls(); int x,y; unsigned int c; for (y=0;y 
    3. GDI

      Canvas - это графический подкомпонент визуальных компонентов в Windows. В борланде есть class TCanvas именем Canvas . У всех окон есть также PaintBoxes,Bitmaps,... Это интерфейс GDI между Windows и вашим приложением. Он имеет подкомпоненты, такие как Pen,Brush,Font для линий, заливок или текстовой бумаги, текстовые чернила.

       Form1->Canvas->Pen->Color=clYellow; Form1->Canvas->MoveTo(10,10); Form1->Canvas->LineTo(100,150); - Form1->Canvas->Pen->Color=clYellow; Form1->Canvas->MoveTo(10,10); Form1->Canvas->LineTo(100,150); 

      где Form1 - мое окно VCL, этот код рисует желтую линию.

      В GDI есть много функций, таких как Arc,Ellipse,Pixels[][],... см. Сборку с помощью вашей IDE для получения дополнительной информации.

    4. GDI Bitmap

      это особый объект, это bitmap с графическим дескриптором ОС (контекст устройства DC ). Это позволяет растровому изображению быть чем-то вроде windows и иметь доступ к GDI

       Graphics::TBitmap *bmp=new Graphics::TBitmap; bmp->Width=100; bmp->Height=100; bmp->HandleType=bmDIB; // allows use of ScanLine bmp->PixelFormat=pf32bit; // 32bit the same as int so we can use int* for pixels pointer 

      это создает bitmap VCL и устанавливает его на 100x100x32bit с прямым доступом. Теперь вы можете получить доступ ScanLine свойству ScanLine . Также присутствует bmp->Canvas чтобы вы могли делать все вещи GDI .

       int *p=bmp->ScanLine[10]; // p = pointer to y=10 line of bitmap p[20]=0; // draw dot on x=20,y=10 color=0x00000000 which is black int c = p[15]; // read pixel x=15,y=10 from bitmap to c 

      Будьте осторожны, чтобы остаться с x,y внутри растрового изображения или исключение. Цветовое кодирование зависит от pixelformat обычно составляет 0x00RRGGBB или 0x00BBGGRR . Я думаю, что этот подход является лучшим вариантом для вас, и вы можете привлечь любой объект GDI к любому другому объекту GDI

       Form1->Canvas->Draw(0,0,bmp); 

      это рисует ваше bitmap в окно, чтобы вы могли видеть его на самом деле.

    5. Графическая библиотека

      Есть много, но наиболее часто используются OpenGL DirectX . Я предпочитаю OpenGL, потому что его проще реализовать (по крайней мере для стартеров), а OpenGL - кросс-платформенный DirectX - это только windows. Также при запуске кодирования не было DirecX . Когда я начал использовать OpenGL, у всех вендоров это было включено в драйверах. Теперь единственными поставщиками, которые по-прежнему актуальны, являются nVidia и ATI (AMD) . Между ними почти всегда возникает проблема с драйверами, но в целом nVidia лучше подходит для OpenGL (имеет ошибки в реализации DirectX), и ATI (только версии AMD) лучше подходит для DirectX (имеет ошибки в реализации OpenGL ). Но для основных операций вы в порядке (проблемы попадают на более сложные функции)

      Продавцы, такие как Intel, SiS , ... остановили свои реализации на более новых версиях OpenGL, по крайней мере, я не знаю ни одного драйвера лучше, чем OpenGL 3.3 для них

      Чтобы начать работу с OpenGL, см. OpenGL get Device Context

    Я настоятельно рекомендую сначала начать с GDI + Bitmap. вы можете много сделать с ними, я все еще использую его для не комплексного рендеринга.

    Как уже упоминалось ранее, я являюсь borland (стиль VCL ), поэтому, если вы используете другой компилятор / IDE, измените имена объектов GDI, чтобы они соответствовали вашей среде. Я думаю, что Canvas тот же, и bitmap - это HBitmap но лучше проверьте вашу помощь / документы, по крайней мере, вы знаете, что искать.

    Надеюсь, это поможет немного.

    [Edit1] другие платформы

    • простой gfx в linux: пример X11 / Xlib.h
    Давайте будем гением компьютера.