/***************************************************************************/ /* TRABALHO CV: MANIPULACAO DE IMAGENS em HSV */ /* */ /* Prof. : AURA CONCI */ /* Aluno : JORGE LUIZ DE ALMEIDA FERREIRA */ /* */ /* OBJETIVO : */ /* */ /* O objetivo deste programa e o de modificar determinadas cores, es- */ /* colhidas pelo usuario, em outras cores, tambem escolhidas pelo usuario. */ /* */ /* METODOLOGIA : */ /* */ /* A forma utilizada neste programa para fazer tais modificacoes con- */ /* siste em transformar o conjunto de cores do sistema RGB para um sistema */ /* onde a variavel cor nao seja uma combinacao linear de cores basicas, co */ /* mo ocorre no sistema RGB, mas sim uma variavel independente e perfeita- */ /* mente determinavel. O sistema auxiliar escolhido foi o sistema */ /* HSV (hue,saturation,value) onde as variaveis cor,saturacao e brilho sao */ /* definidas dentro de intervalos fixos ( cor (0,360] saturacao (0,1) bri */ /* lho (0,1). Neste sistema para se variar uma determinada cor basta alte- */ /* rar a propria variavel cor. Uma vez a alteracao feita retorna-se ao sis */ /* tema original RGB. */ /* */ /* ARQUIVOS UTILIZAVEIS : PCX */ /* */ /***************************************************************************/ #include #include #include #include #include #include #include #include #include #include #define INDEFINIDO 500 typedef struct { unsigned char r,g,b; } aux; typedef struct { int r,g,b; } laux; typedef struct { double r,g,b; char flag; } faux; typedef struct { unsigned char r,g,b; float h,s,v; } visual; /*ESTRUTURA DE DADOS DO CABECALHO DO PCX */ struct { unsigned char ident,ver,encouding,bit_por_pixel; int xmin,ymin,xmax,ymax; int resolx,resoly; unsigned char palette[48]; unsigned char reservado, planos_de_cores; int bit_por_linha,palette_info; unsigned char resto[58]; } PCX_INFO; long int tam_arq; char nome[100] = "",til[100] = ""; /***************************** M A I N ********************************/ void main(void) { FILE *ARQUIVO,*LER_INICIO_ARQ (void); void LER_INFORMACOES(FILE*); aux* LER_FINAL_ARQ(FILE*,aux*); void MENSAGEM(char*,int); faux* MONTA_HSV(faux*,laux*,float,int); laux* REMONTA_RGB(faux*,laux*,float,int); faux* ALTERA_PALETTE(faux*,int); void GRAVA_ARQUIVO(FILE *,laux *, int); void INTRODUCAO(void); void MOSTRA_PALETTE(laux*,faux*,int); void PERGUNTA(char *,int,int); register int i; char continua = 'S',flag = 'S'; int k; aux *palette,*ipalette; laux *lpalette,*ilpalette; float MRGB; faux *fpalette,*ifpalette; INTRODUCAO( ); do { flag = 'S'; strcpy(nome,""); strcpy(til,""); ARQUIVO = LER_INICIO_ARQ ( ); LER_INFORMACOES(ARQUIVO); if((int)PCX_INFO.bit_por_pixel >= 8 ) { k = 256; MRGB = 255; } else { k = 16; MRGB =256; } palette = (aux*) malloc(k*sizeof(aux)); if(!palette) { clrscr( ); MENSAGEM("MEMORIA INSUFICIENTE - PROGRAMA ABORTADO",12); exit(10); } ipalette = palette; lpalette = (laux*) malloc(k*sizeof(laux)); if(!lpalette) { clrscr( ); MENSAGEM("MEMORIA INSUFICIENTE - PROGRAMA ABORTADO",12); exit(10); } ilpalette = lpalette; if( k == 256) { palette = LER_FINAL_ARQ(ARQUIVO,palette); for(i = 0 ; i < k ; i++) { lpalette[i].r = (int)palette[i].r; lpalette[i].g = (int)palette[i].g; lpalette[i].b = (int)palette[i].b; } palette = ipalette; } else { for(i = 0 ; i < 3*k ; i+=3) { lpalette[i/3].r = (int)PCX_INFO.palette[i]; lpalette[i/3].g = (int)PCX_INFO.palette[i+1]; lpalette[i/3].b = (int)PCX_INFO.palette[i+2]; } } lpalette = ilpalette; fpalette = (faux*) malloc(k*sizeof(faux)); if(!fpalette) { clrscr( ); MENSAGEM("MEMORIA INSUFICIENTE - PROGRAMA ABORTADO",12); exit(10); } ifpalette = fpalette; fpalette = MONTA_HSV(fpalette,lpalette,MRGB,k); lpalette = ilpalette; fpalette = ifpalette; do { clrscr( ); MENSAGEM("TRABALHO DE MANIPULACAO DE IMAGENS",2); MENSAGEM("TRANSFOMACAO DE CORES NO SISTEMA HSV",4); MENSAGEM(til,7); PERGUNTA("Voce Quer Ver a Tabela de Cores (S/N) : ",4,14); MENSAGEM("ESTA ROTINA SERVE PARA AUXILIA-LO NA SELECAO DAS CORES A SEREM MODIFICADAS",24); flushall( ); flag = toupper(getch( )); }while(!strchr("SN",flag)); if(flag == 'S') { MOSTRA_PALETTE(lpalette,fpalette,k); lpalette = ilpalette; fpalette = ifpalette; clrscr( ); MENSAGEM("TRABALHO DE MANIPULACAO DE IMAGENS",2); MENSAGEM("TRANSFOMACAO DE CORES NO SISTEMA HSV",4); MENSAGEM(til,7); PERGUNTA("Voce quer Continuar (S/N) : ",4,14); do { flushall( ); continua = toupper(getch( )); }while(!strchr("SN",continua)); } if( 'S' == continua ) { fpalette = ALTERA_PALETTE(fpalette,k); palette = ipalette; fpalette = ifpalette; lpalette = REMONTA_RGB(fpalette,lpalette,MRGB,k); if( PCX_INFO.bit_por_pixel < 8 ) { for(i = 0 ; i < 3*k ; i+=3) { PCX_INFO.palette[i] = (char)lpalette[i/3].r; PCX_INFO.palette[i+1] = (char)lpalette[i/3].g; PCX_INFO.palette[i+2] = (char)lpalette[i/3].b; } } lpalette = ilpalette; GRAVA_ARQUIVO(ARQUIVO,lpalette,k); } fclose(ARQUIVO); free(lpalette); free(fpalette); free(palette); clrscr( ); MENSAGEM("TRABALHO DE MANIPULACAO DE IMAGENS",2); MENSAGEM("TRANSFOMACAO DE CORES NO SISTEMA HSV",4); MENSAGEM("OPERACAO TERMINADA - ENCERAR PROGRAMA ( S / N )",14); flushall( ); continua = toupper(getch( )); }while(continua == 'N'); clrscr( ); return; } /*****************L E R _ I N I C I O _ A R Q U I V O *****************/ /* */ /* Esta rotina tem por objetivo abrir o arquivo de trabalho. */ /**************************************************************************/ FILE* LER_INICIO_ARQ (void) { int PROCURA (char*); void MENSAGEM(char*,int); void PERGUNTA(char *,int,int); FILE *input_arq; char carac[200]; int coordy; struct ffblk f; clrscr( ); MENSAGEM("TRABALHO DE MANIPULACAO DE IMAGENS",2); MENSAGEM("TRANSFOMACAO DE CORES NO SISTEMA HSV",4); gotoxy(5,8); coordy = PROCURA("*.pcx"); do { strcpy(carac,""); PERGUNTA("\n\nInforme o Nome do Arquivo de Trabalho ( s/ext. ): ",4,coordy+2); scanf("%s",&carac); strcat(carac,".pcx"); }while( findfirst(carac,&f,0) != 0 ); if((input_arq = fopen(carac,"rb"))==NULL) { clrscr( );MENSAGEM("NAO E POSSIVEL ABRIR ARQUIVO ",14);exit(9);} tam_arq = f.ff_fsize; rewind(input_arq); strcpy(nome,carac); return input_arq; } /******************* L E R _ I N F O R M A C O E S **********************/ /* */ /* Esta rotina informa o diretorio de trabalho e lista os arquivos .PCX */ /* existentes neste diretorio. */ /* Tem tambem por objetivo obter o nome do arquivo de trabalho, verifi- */ /* sua existencia e analisar sua identificacao. */ /* */ /***************************************************************************/ void LER_INFORMACOES(FILE *ARQUIVO) { void MENSAGEM(char*,int); int tam; clrscr( ); MENSAGEM("TRABALHO DE MANIPULACAO DE IMAGENS",2); MENSAGEM("TRANSFOMACAO DE CORES NO SISTEMA HSV",4); strcpy(til,"Manipulando o Arquivo : "); strcat(til,nome); MENSAGEM(til,7); rewind(ARQUIVO); tam = fread(&PCX_INFO,sizeof(PCX_INFO),1,ARQUIVO); if(tam != 1) { MENSAGEM("ERRO DE LEITURA DE ARQUIVO !!!",15); MENSAGEM("PROGRAMA ABORTADO",16); exit(10); } if( PCX_INFO.ident != 0x0A) { MENSAGEM("EXISTE ALGUM PROBLEMA !!!",15); MENSAGEM("ESTE ARQUIVO NAO E PCX",16); exit(10); } return; } /*************** L E R _ F I N A L _ D O _ A R Q U I V O *****************/ /* */ /* Rotina utilizada para ler a tabela de cores em figuras com resolucao */ /* de 256 cores. So e utilizada se o numero de bits por pixel for maior */ /* ou igual a 8. */ /* */ /***************************************************************************/ aux* LER_FINAL_ARQ(FILE *ARQUIVO,aux *p_aux) { void MENSAGEM(char*,int); register int i; int teste; aux *ip_aux = p_aux; MENSAGEM("AGUARDE - LENDO TABELA DE CORES NO FINAL DO ARQUIVO",14); rewind(ARQUIVO); teste = fseek(ARQUIVO,tam_arq - 768,SEEK_SET); if( teste != 0 ) { clrscr( ); MENSAGEM("ERRO DE LEITURA DE ARQUIVO !!!",15); MENSAGEM("PROGRAMA ABORTADO",16); exit(10); } for(i = 0 ; i < 256 ; i++) { p_aux[i].r =getc(ARQUIVO); p_aux[i].g =getc(ARQUIVO); p_aux[i].b =getc(ARQUIVO); } MENSAGEM("",14); return ip_aux; } /************************* M O N T A _ H S V ***************************/ /* */ /* Rotina para normalizar os valores RGB e transformar RGB em HSV. Tra */ /* balhando em conjunto com a rotina RGB_TO_HSV, que realiza realmente a */ /* transformacao entre os dois sistemas. */ /* */ /* *//* */ /***************************************************************************/ faux* MONTA_HSV(faux* fpalette,laux* palette,float MRGB, int n) { void RGB_TO_HSV(faux*,faux*); void MENSAGEM(char*,int); faux *RGB,*IRGB,*HSV,*IHSV,*ifpalette = fpalette; laux *ipalette = palette; register int i; RGB = (faux*) malloc(sizeof(faux)); if(!RGB) { clrscr( ); MENSAGEM("MEMORIA INSUFICIENTE - PROGRAMA ABORTADO",12); exit(10); } IRGB = RGB; HSV = (faux*) malloc(sizeof(faux)); if(!HSV) { clrscr( ); MENSAGEM("MEMORIA INSUFICIENTE - PROGRAMA ABORTADO",12); exit(10); } IHSV = HSV; for( i = 0 ; i < n ; i++) { RGB->r = ((double)palette[i].r)/MRGB; RGB->g = ((double)palette[i].g)/MRGB; RGB->b = ((double)palette[i].b)/MRGB; RGB_TO_HSV(RGB,HSV); fpalette[i].r = HSV->r; fpalette[i].g = HSV->g; fpalette[i].b = HSV->b; fpalette[i].flag = '0'; RGB = IRGB; HSV = IHSV; } palette = ipalette; fpalette = ifpalette; free(IRGB); free(IHSV); return fpalette; } /************************ R G B _ TO _ H S V *************************/ void RGB_TO_HSV(faux* RGB,faux *HSV) { double MAXIMO(faux*); double MINIMO(faux*); double max = 0 , min = 0, delta; faux *IHSV = HSV; HSV->r = 0; HSV->g = 0; HSV->b = 0; max = MAXIMO(RGB); min = MINIMO(RGB); HSV->b = max; if( max != 0) HSV->g = (max - min)/max; else HSV->g = 0; if ( HSV->g == 0 ) HSV->r = INDEFINIDO; if( HSV->g != 0) { delta = max - min; if(RGB->r == max) HSV->r = (RGB->g - RGB->b)/delta; else if(RGB->g == max) HSV->r = 2 + (RGB->b - RGB->r)/delta; else if(RGB->b == max) HSV->r = 4 + (RGB->r - RGB->g)/delta; HSV->r*=60; if( HSV->r < 0 ) HSV->r+=360; } HSV = IHSV; return ; } /***************************** M A X I M O *******************************/ double MAXIMO(faux *RGB) { if(RGB->r >= RGB->g && RGB->r >= RGB->b) return RGB->r; if(RGB->g >= RGB->r && RGB->g >= RGB->b) return RGB->g; if(RGB->b >= RGB->r && RGB->b >= RGB->g) return RGB->b; } /***************************** M I N I M O *******************************/ double MINIMO(faux *RGB) { if(RGB->r <= RGB->g && RGB->r <= RGB->b) return RGB->r; if(RGB->g <= RGB->r && RGB->g <= RGB->b) return RGB->g; if(RGB->b <= RGB->r && RGB->b <= RGB->g) return RGB->b; } /*********************** R E M O N T A _ R G B *************************/ /* */ /* Esta rotina e utilizada apos a transformacao de cores e serve para re */ /* compor o sistema original do arquivo ( RGB ). Trabalha em conjunto com */ /* a rotina HSV_TO_RGB. */ /* */ /***************************************************************************/ laux* REMONTA_RGB(faux *fpalette,laux *palette,float MRGB,int n) { void HSV_TO_RGB(faux*,faux*); void MENSAGEM(char*,int); faux *RGB,*HSV,*IRGB,*IHSV,*ifpalette = fpalette; laux *ipalette = palette; register int i; int cont = 0; RGB = (faux*) malloc(sizeof(faux)); if(!RGB) { clrscr( ); MENSAGEM("MEMORIA INSUFICIENTE - PROGRAMA ABORTADO",12); exit(10); } IRGB = RGB; HSV = (faux*) malloc(sizeof(faux)); if(!HSV) { clrscr( ); MENSAGEM("MEMORIA INSUFICIENTE - PROGRAMA ABORTADO",12); exit(10); } IHSV = HSV; for( i = 0 ; i < n ; i++) { HSV->r = (double)fpalette[i].r; HSV->g = (double)fpalette[i].g; HSV->b = (double)fpalette[i].b; HSV_TO_RGB(HSV,RGB); palette[i].r = (int)(RGB->r*MRGB); palette[i].g = (int)(RGB->g*MRGB); palette[i].b = (int)(RGB->b*MRGB); cont++; } palette = ipalette; fpalette = ifpalette; free(IRGB); free(IHSV); return palette; } /*********************** H S V _ T O _ R G B *************************/ void HSV_TO_RGB(faux *HSV,faux *RGB) { void MENSAGEM(char*,int); faux *IRGB = RGB; double f,p,q,t,opc; RGB->r = 0; RGB->g = 0; RGB->b = 0; if( HSV->g == 0 ) { if( HSV->r == INDEFINIDO) { RGB->r = HSV->b; RGB->g = HSV->b; RGB->b = HSV->b; } else {MENSAGEM("PROGRAMA ABORTADO",14); exit(10);} } else { if(HSV->r == 360) HSV->r = 0; HSV->r/=60; opc = floor(HSV->r); f = HSV->r - opc; p = HSV->b*(1 - HSV->g); q = HSV->b*(1 - (HSV->g*f)); t = HSV->b*(1 - (HSV->g*(1-f))); switch ((int)opc) { case 0 : { RGB->r = HSV->b; RGB->g = t; RGB->b = p; break; } case 1 : { RGB->r = q; RGB->g = HSV->b; RGB->b = p; break; } case 2 : { RGB->r = p; RGB->g = HSV->b; RGB->b = t; break; } case 3 : { RGB->r = p; RGB->g = q; RGB->b = HSV->b; break; } case 4 : { RGB->r = t; RGB->g = p; RGB->b = HSV->b; break; } case 5 : { RGB->r = HSV->b; RGB->g = p; RGB->b = q; break; } } } RGB = IRGB; return; } /******************** A L T E R A _ P A L E T T E **********************/ /* */ /* Rotina utilizada para solicitar a faixa de cores a ser modificada e */ /* o angulo a ser girado esta faixa de cores. Utiliza a rotina ALTERA pa */ /* ra fazer tal rotacao. */ /* */ /***************************************************************************/ faux* ALTERA_PALETTE(faux* HSV,int n) { void PERGUNTA (char*,int,int); void MENSAGEM (char*,int); faux* ALTERA(faux*,float,float,float,int); faux *IHSV = HSV; float cormin,cormax,incremento; int quant; do { PERGUNTA("Informe o Numero de Cores a Serem Modificadas : ",4,14); scanf("%d",&quant); }while(quant < 0 || quant > n); do { clrscr( ); MENSAGEM("TRABALHO DE MANIPULACAO DE IMAGENS",2); MENSAGEM("TRANSFOMACAO DE CORES UTILIZANDO O SISTEMA HSV",4); MENSAGEM(til,6); MENSAGEM("NO SISTEMA HSV COR E UM NUMERO REAL QUE VARIA ENTRE : ( 0, 360 ]",16); MENSAGEM("CORRELACAO ENTRE COR E ANGULO NO SISTEMA HSV",18); PERGUNTA("VERMELHO - 0",1,20); PERGUNTA("CYAN - 180",1,22); PERGUNTA("AMARELO - 60",33,20); PERGUNTA("AZUL - 240",33,22); PERGUNTA("VERDE - 120",61,20); PERGUNTA("MAGENTA - 300",61,22); PERGUNTA("Informe a Faixa de Cores a Ser Modificada : ",4,8); MENSAGEM("VALORES EM GRAUS",25); flushall( ); PERGUNTA("Limite Minimo : ",53,8); scanf("%f",&cormin); flushall( ); PERGUNTA("Limite Maximo : ",53,10); scanf("%f",&cormax); PERGUNTA("Informe o Angulo de rotacao desta Faixa de Cores : ",4,12); scanf("%f",&incremento); HSV = ALTERA(HSV,cormin,cormax,incremento,n); HSV = IHSV; quant--; }while( quant > 0 ); return HSV; } /**************************** A L T E R A ********************************/ faux* ALTERA(faux* HSV,float cormin,float cormax,float incremento,int n) { void MENSAGEM(char*,int); register int i; faux *IHSV = HSV; for(i = 0; i < n; i++ ) { if(cormin < 0) { if((HSV[i].r >= cormin + 360) && HSV[i].r != INDEFINIDO && HSV[i].flag == '0') { HSV[i].r+=incremento; HSV[i].flag = '1'; while(HSV[i].r > 360 ) HSV[i].r-=(360 - cormin); } } if(cormax > 360) { if((HSV[i].r <= cormax - 360) && HSV[i].r != INDEFINIDO && HSV[i].flag == '0') { HSV[i].r+=incremento; HSV[i].flag = '1'; while(HSV[i].r > 360 ) HSV[i].r-=(360 - cormax); } } if(HSV[i].r >= cormin && HSV[i].r <= cormax && HSV[i].flag == '0') { HSV[i].r+=incremento; HSV[i].flag = '1'; while(HSV[i].r > 360 ) HSV[i].r-=360; } } HSV = IHSV; return HSV; } /********************** G R A V A _ A R Q U I V O **********************/ void GRAVA_ARQUIVO(FILE *OLD_ARQ,laux *palette, int n) { void MENSAGEM(char *, int); void PERGUNTA(char*,int,int); void TRANSFERE(FILE*,FILE*,char*,int); struct ffblk f; FILE* NEW_ARQ; char *dados,*idados,Arq[100],flag = 'S'; register int i; int teste,done; long int decremento = tam_arq; laux *ipalette = palette; clrscr( ); MENSAGEM("TRABALHO DE MANIPULACAO DE IMAGENS",3); MENSAGEM("TRANSFOMACAO DE CORES UTILIZANDO O SISTEMA HSV",5); MENSAGEM(til,7); do { strcpy(Arq,""); MENSAGEM("",24); PERGUNTA("Informe o Nome do Arquivo Modificado ( s/ Ext. ): ",4,14); scanf("%s",&Arq); strcat(Arq,".pcx"); done = findfirst(Arq,&f,0); if(done == 0) { MENSAGEM("ARQUIVO EXISTENTE !!!",14); flushall( ); PERGUNTA("Mudar o Nome ( S/N ): ",4,24); flushall( ); flag = toupper(getch( )); } } while( done == 0 && flag != 'N' ); if((NEW_ARQ = fopen(Arq,"wb"))==NULL) { clrscr( );MENSAGEM("NAO E POSSIVEL ABRIR ARQUIVO ",14);exit(9);} dados = (char*) malloc(512*sizeof(char)); if(!dados) { clrscr( ); MENSAGEM("MEMORIA INSUFICIENTE - PROGRAMA ABORTADO",12); exit(10); } idados = dados; teste = fwrite(&PCX_INFO,sizeof(PCX_INFO),1,NEW_ARQ); if(0 == teste) { MENSAGEM("ERRO DE ESCRITA DE ARQUIVO !!!",15); MENSAGEM("PROGRAMA ABORTADO",16); exit(10); } if( n <= 16 ) { fseek(OLD_ARQ,128,SEEK_SET); fseek(NEW_ARQ,128,SEEK_SET); decremento-=128; while(decremento > 512) { TRANSFERE(NEW_ARQ,OLD_ARQ,dados,512); dados = idados; decremento-=512; } TRANSFERE(NEW_ARQ,OLD_ARQ,dados,(int)decremento); } else { fseek(OLD_ARQ,128,SEEK_SET); fseek(NEW_ARQ,128,SEEK_SET); decremento = tam_arq - 896; while(decremento > 768) { TRANSFERE(NEW_ARQ,OLD_ARQ,dados,512); dados = idados; decremento-=512; } TRANSFERE(NEW_ARQ,OLD_ARQ,dados,(int)decremento); fseek(NEW_ARQ,tam_arq - 768,SEEK_SET); for(i = 0 ; i < 256 ; i++) { putc(palette[i].r,NEW_ARQ); putc(palette[i].g,NEW_ARQ); putc(palette[i].b,NEW_ARQ); } palette = ipalette; } fclose(NEW_ARQ); free(dados); return; } /************************* T R A N S F E R E *****************************/ void TRANSFERE(FILE* NEW_ARQ,FILE* OLD_ARQ,char *dados,int quant) { void MENSAGEM(char*,int); char *idados = dados; if(!fread(dados,quant,1,OLD_ARQ)) {MENSAGEM("ERRO LEITURA - APERTE QUALQUE TECLA",14);flushall( );getch( );} dados = idados; if(!fwrite(dados,quant,1,NEW_ARQ)) {MENSAGEM("ERRO GRAVACAO - APERTE QUALQUE TECLA",14);flushall( );getch( );} return; } /************************** M E N S A G E M ******************************/ void MENSAGEM (char mens[ ],int coordy) { gotoxy((int)(80 - strlen(mens))/2,coordy); delline( ); printf("%s",mens); } /******************************* P R O C U R A *****************************/ int PROCURA(char *resp) { void MENSAGEM(char *,int); void PERGUNTA(char *,int,int); struct ffblk f; char path[200]="",nome[200] = ""; int done = 0,coordx[3] = {1,25,50},j = 0,i = 10; struct dfree livre; PERGUNTA("Diretorio : ",1,8); strcpy(path,""); strcpy(nome,getcwd(path,120)); printf("%s\n\n",nome); done = findfirst(resp,&f,0); if( !done) {MENSAGEM("",14);MENSAGEM("",23);} while( !done ) { gotoxy(coordx[j],i); printf("%12s %8ld",f.ff_name,f.ff_fsize); j++; if(j > 2) { j = 0 ; i++ ; } done = findnext(&f); } getdfree(0,&livre); printf("\n\nEspaco Disponivel : "); printf("%9.0f Bytes\n",(float)livre.df_sclus*livre.df_bsec*livre.df_avail); return i; } /************************** P E R G U N T A ******************************/ void PERGUNTA (char pergunta[ ],int x,int y) { gotoxy(x,y); printf(pergunta); return; } void INTRODUCAO(void) { void MENSAGEM(char*,int); void PERGUNTA(char*,int,int); clrscr(); MENSAGEM("TRABALHO FINAL DE INTRODUCAO A MANIPULACAO DE IMAGENS",2); PERGUNTA("Prof. : AURA CONCI",4,4); PERGUNTA("Aluno : JORGE LUIZ DE ALMEIDA FERREIRA",4,6); PERGUNTA("OBJETIVO :",4,8); PERGUNTA("O objetivo deste programa e o de modificar determinadas cores, es-",10,10); PERGUNTA("colhidas pelo usuario, para outras cores, tambem escolhidas pelo usuario.",4,11); PERGUNTA("METODOLOGIA :",4,13); PERGUNTA("A forma utilizada neste programa para fazer tais modificacoes con-",10,15); PERGUNTA("siste em transformar o conjunto de cores do sistema RGB para um sistema",4,16); PERGUNTA("onde a variavel cor nao seja uma combinacao linear de cores basicas, co-",4,17); PERGUNTA("mo ocorre no sistema RGB, mas sim uma variavel independente e perfeita-",4,18); PERGUNTA("mente determinavel. O sistema auxiliar escolhido foi o sistema",4,19); PERGUNTA("HSV (hue,saturation,value) onde as variaveis cor, saturacao e brilho sao",4,20); PERGUNTA("definidas dentro de intervalos fixos {cor (0,360], saturacao (0,1), bri-",4,21); PERGUNTA("lho (0,1)}. Neste sistema para se variar uma determinada cor basta alte-",4,22); PERGUNTA("rar a propria variavel cor. Uma vez a alteracao feita retorna-se ao sis-",4,23); PERGUNTA("tema original RGB. ",4,24); MENSAGEM("**** APERTE QUALQUER TECLA ****",25); flushall( ); getch( ); return; } /********************** M O S T R A _ P A L E T T E ********************/ /* */ /* Esta rotina tem por finalidade auxiliar o usuario na selecao das co- */ /* res a serem modificadas. Basicamente ela apresenta a tabela de cores e */ /* indica qual o valor da respectiva cor no sistema HSV. */ /* */ /***************************************************************************/ void MOSTRA_PALETTE(laux *palette,faux *fpalette,int k) { void MONTA_TELA(visual*,int,int,int,int,int,int); char selec = '0',flag = '0'; register int i,j; int driver,mode; int size; int pos,quant,numero; laux *ipalette = palette; faux *ifpalette = fpalette; visual *palette_aux , *ipalette_aux; struct viewporttype info; driver = DETECT; initgraph(&driver,&mode,""); getviewsettings( (struct viewporttype far *) &info); size = 0; for(i = 0 ; i < k ; i++) if(fpalette[i].r != 500) size++; fpalette = ifpalette; palette_aux = (visual*) malloc((size+1)*sizeof(visual)); if(!palette_aux) { clrscr( ); MENSAGEM("MEMORIA INSUFICIENTE - PROGRAMA ABORTADO",12); exit(10); } ipalette_aux = palette_aux; i = 0; j = 0; do { if(fpalette[j].r != 500) { palette_aux[i].r = palette[j].r; palette_aux[i].g = palette[j].g; palette_aux[i].b = palette[j].b; palette_aux[i].h = fpalette[j].r; palette_aux[i].s = fpalette[j].g; palette_aux[i].v = fpalette[j].b; i++; } j++; }while( j < k ); palette = ipalette; fpalette = ifpalette; palette_aux = ipalette_aux; pos = 0; settextstyle(SMALL_FONT,HORIZ_DIR,5); if( k == 16 ) { quant = size; outtextxy(info.right/2,info.bottom,"air"); MONTA_TELA(palette_aux,info.left,info.top,info.right,info.bottom,pos,quant); palette = ipalette; fpalette = ifpalette; palette_aux = ipalette_aux; getch( ); } else { if( k == 256 && size <= 15) quant = size; else quant = 15; numero = quant; settextjustify(LEFT_TEXT,BOTTOM_TEXT); MONTA_TELA(palette_aux,info.left,info.top,info.right,info.bottom,pos,numero); palette = ipalette; fpalette = ifpalette; palette_aux = ipalette_aux; pos = quant; do { settextjustify(CENTER_TEXT,BOTTOM_TEXT); if(pos < quant ) outtextxy(info.right/2,info.bottom - 0.01*info.bottom,"

roximas Cores - air"); else if(pos >= quant && numero == quant ) outtextxy(info.right/2,info.bottom,"

roximas Cores nteriores - air"); else outtextxy(info.right/2,info.bottom,"Cores nteriores - air"); do { flushall( ); selec = toupper(getch( )); if(flag == '1' && selec == 'P') selec = '1'; if(size <= 16 && (selec == 'P' || selec == 'A')) selec = '1'; }while(!strchr("PAS",selec)); flag = '0'; switch (selec) { case 'P' : { numero = quant; if(pos < size) { cleardevice( ); if( size - pos > 2*quant) { pos+=quant; MONTA_TELA(palette_aux,info.left,info.top,info.right,info.bottom,pos,quant); } else if( size - pos > quant) { pos+=quant; } if(size - pos < quant) { numero = size - pos; cleardevice( ); MONTA_TELA(palette_aux,info.left,info.top,info.right,info.bottom,pos,numero); pos = size - numero - quant; flag = '1'; } } palette = ipalette; fpalette = ifpalette; palette_aux = ipalette_aux; break; } case 'A' : { if(pos >= quant) { pos-=quant; if(numero < quant ) pos+=quant; cleardevice( ); numero = quant; if( size - pos > quant) { MONTA_TELA(palette_aux,info.left,info.top,info.right,info.bottom,pos,quant); } if(size - pos <= quant) { numero = quant; MONTA_TELA(palette_aux,info.left,info.top,info.right,info.bottom,pos,numero); } } palette = ipalette; fpalette = ifpalette; palette_aux = ipalette_aux; break; } } }while(selec != 'S'); } cleardevice( ); closegraph( ); free(palette_aux); return; } void MONTA_TELA(visual *palette_aux,int left,int top,int right,int bottom,int pos,int quant) { register int i; int coordx,coordy,dx,dy,distx,disty,j = 0,int1,int2; char cor[60],informa[100]; visual *ipalette_aux = palette_aux; coordx = (int)(0.01799687*right); coordy = (int)(0.130653*bottom); dx = (int)(0.0657277*right); dy = (int)(0.095477*bottom); distx = (int)(0.06259781*right); disty = (int)(/*0.120603*/0.30150754*bottom); int1 = (int)(0.004695*right); int2 = (int)(0.006260*right); settextjustify(CENTER_TEXT,TOP_TEXT); outtextxy(right/2,top,"TABELA DE CORES - COR SISTEMA HSV"); settextjustify(LEFT_TEXT,BOTTOM_TEXT); settextstyle(SMALL_FONT,HORIZ_DIR,4); for(i = 1 ; i <= quant ; i++) { setrgbpalette(i,palette_aux[pos].r,palette_aux[pos].g,palette_aux[pos].b); setpalette(i,i); setcolor(i); rectangle(coordx,coordy,coordx + dx,coordy + dy); rectangle(coordx + int1,coordy + int1,coordx + dx - int1,coordy + dy - int1); setfillstyle(SOLID_FILL,i); floodfill(coordx + int2,coordy + int2,i); strcpy(informa,"H = "); strcpy(cor,""); gcvt(palette_aux[pos].h,4,cor); strcat(informa,cor); setcolor(1); outtextxy(coordx - 0.1*dx,coordy + 1.5*dy,informa); strcpy(informa,"S = "); strcpy(cor,""); gcvt(palette_aux[pos].s,3,cor); strcat(informa,cor); outtextxy(coordx - 0.1*dx,coordy + 1.9*dy,informa); strcpy(informa,"V = "); strcpy(cor,""); gcvt(palette_aux[pos].v,3,cor); strcat(informa,cor); outtextxy(coordx - 0.1*dx,coordy + 2.3*dy,informa); strcpy(informa,"R = "); strcpy(cor,""); gcvt((float)palette_aux[pos].r,4,cor); strcat(informa,cor); setcolor(1); outtextxy(coordx - 0.1*dx,coordy + 2.7*dy,informa); strcpy(informa,"G = "); strcpy(cor,""); gcvt((float)palette_aux[pos].g,3,cor); strcat(informa,cor); outtextxy(coordx - 0.1*dx,coordy + 3.1*dy,informa); strcpy(informa,"B = "); strcpy(cor,""); gcvt((float)palette_aux[pos].b,3,cor); strcat(informa,cor); outtextxy(coordx - 0.1*dx,coordy + 3.5*dy,informa); coordx+=(dx+distx); pos++; j++; if( j >= 8 ) { j = 0; coordx = (int)(0.01799687*right); coordy+= (int)(dy + disty); } } palette_aux = ipalette_aux; settextstyle(SMALL_FONT,HORIZ_DIR,5); return; }