Exibe uma matriz de colors em C

Meu programa tanto escreve uma leituras de matrizes de colors como esta:

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

Como posso exibir essa matriz na canvas em C?

Renderização de charts:

Eu estou acostumado a win32 e ambientes Borland C ++, então eu fico com ele, mas as diferenças em outros ambientes são principalmente apenas em nomes de class. Primeiro algumas abordagens:

  1. modos de console / texto

    você pode usar charts de texto ( arte ASCII eu acho em inglês). Onde ponto é representado por caractere . A intensidade é feita por caracteres mais ou menos preenchidos. Geralmente tem uma tabela de caracteres classificados por intensidade como " ..:+*#" e use isso em vez de colors. Para imprimir algo pode usar iostream como cout < < "text" << endl; ou printf de stdio eu acho (não usando saída de console de estilo antigo por mais de uma década).

    Modos de texto videoram ( VRAM ) começa em 0B000:0000 se você tem privilégios para ele, você pode fazer access direto como este:

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

    mas no Windows você pode esquecer o access direto

  2. Modo gfx VGA

    no Windows você pode esquecer isso também ... Aqui um pequeno exemplo:

      //============================================================================== 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; } } //============================================================================== 

    O access VESA é semelhante, mas você precisa lidar com o cruzamento de segmentos e a paginação. Aqui pequeno exemplo do 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 é um subcomponente gráfico de componentes visuais no Windows. Em borland é a class TCanvas chamada Canvas . Todas as janelas também tem PaintBoxes,Bitmaps,... É a interface GDI entre o Windows e seu aplicativo. Possui subcomponentes como Pen,Brush,Font para linhas, preenchimentos ou texto, tinta de textos.

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

    onde Form1 é minha janela VCL , este código desenha uma linha amarela.

    O GDI tem muitas funções como Arc,Ellipse,Pixels[][],... veja a ajuda do seu IDE para obter mais informações.

  4. Bitmap GDI

    Este é um object especial, é um bitmap com identificador gráfico do sistema operacional (contexto de dispositivo DC ). Isso permite que bitmap seja algo como janela e tenha access ao 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 

    isso cria um bitmap VCL e o configura para 100x100x32bit com access direto. Agora você pode acessar a propriedade ScanLine . Também o bmp->Canvas está presente para que você possa fazer todo o material GDI também.

     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 

    Tenha cuidado para ficar com x,y dentro de bitmap ou exceção será lançada. A codificação de colors depende do formato de pixelformat geralmente é 0x00RRGGBB ou 0x00BBGGRR . Eu acho que essa abordagem é a melhor opção para você também pode desenhar qualquer object GDI para qualquer outro object GDI

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

    Isso desenha seu bitmap na janela para que você possa vê-lo na verdade.

  5. Biblioteca de charts

    Existem muitos, mas os mais usados ​​são o OpenGL e o DirectX . Eu prefiro o OpenGL porque é mais simples de implementar (pelo menos para iniciantes) e também o OpenGL é multi-plataforma e o DirectX é somente windows. Além disso, quando eu começo a codificar não havia DirecX . Quando comecei a usar o OpenGL, todos os fornecedores o tinham em drivers incluídos. Agora os únicos fornecedores que ainda estão atualizados são a nVidia e a ATI (AMD) . Há quase sempre algum problema de driver entre eles, mas em geral a nVidia é melhor para OpenGL (tem erros na implementação do DirectX) e ATI (versões AMD somente) é melhor para o DirectX (tem erros na implementação do OpenGL ). Mas, para operações básicas, você está bem (problemas ocorrem em funções mais avançadas)

    Fornecedores como Intel, SiS , ... pararam suas implementações em versões mais novas do OpenGL, pelo menos eu não conheço nenhum driver melhor do que o OpenGL 3.3 para eles

    Para começar a usar o OpenGL, veja o OpenGL get Device Context

Eu recomendo fortemente começar com o Bitmap GDI + primeiro. você pode fazer muito com eles eu ainda estou usando para renderização não complexa.

Como mencionado anteriormente, eu sou o borland (estilo VCL ) amigável, portanto, se você usar um compilador / IDE diferente, altere os nomes de objects GDI para corresponder ao seu ambiente. Eu acho que Canvas é o mesmo e bitmap é HBitmap mas melhor verificar sua ajuda / docs, pelo menos, você sabe o que procurar.

Espero que ajude um pouco.

[Edit1] outras plataformas

  • gfx simples no linux aqui: exemplo X11 / Xlib.h