Lendo bitmap

1. Lendo bitmap

Paulo
paulo_moc

(usa Ubuntu)

Enviado em 18/07/2013 - 02:31h

Olá pessoal, estava lendo um livro e em uma página ele mostra como é uma estrutura de um arquivo de bitmap:

Bitmap file header
Bitmap info header
RGBQUAD(paleta)
Dados da imagem

então tentei criar um código para ler uma imagem bitmap:


#include <stdio.h>
#include <stdlib.h>

#define IMAGEM "teste.bmp"

//WORD == unsigned short %hu
//DWORD == unsigned long %lu
//LONG == long %li

struct bitmap
{
//Cabeçalho do arquivo bitmap
unsigned short bmp_tipo;//Tipo
unsigned long bmp_tam;//Tamanho total do arquivo
unsigned short bmp_reservado1;
unsigned short bmp_reservado2;
unsigned long bp_infocab;//Número de bytes daqui pra frente para acessar o Info header

//Informações para leitura do bitmap(Info reader)
unsigned long leitor_tam;//Tamanho da estrutura
long bmp_larg;//Largura
long bmp_alt;//Altura
unsigned short bmp_planos_cor;//Planos de cor(sempre 1)
unsigned short bmp_bpp;//Bits por pixel
unsigned long bmp_compressao;//Tipo de compressão
unsigned long bmp_tam_img;//Tamanho da imagem em bytes
long bmp_x_pxl_por_mtr;//Pixels por metro em x
long bmp_y_pxl_por_mtr;//Pixels por metro em y
unsigned long bmp_cont_cores;//Número de cores usadas
unsigned long bmp_cont_coresw;//Número de cores improtantes para o windows

//Paleta
unsigned char paleta[256];

//Dados para montagem da imagem(tamanho variável)
unsigned* dados;//Alocar memória antes da leitura dos dados
};

struct bitmap* ler_bitmap(FILE*, int*);
void liberar_bitmap(struct bitmap*);

int main(int argc, char* argv[])
{
int i, t;
FILE* img;
struct bitmap* bmp=NULL;

//Abre arquivo no modo binário
img = fopen(IMAGEM, "r+b");

if(img == NULL){
perror("fopen");
return 0;
}

bmp = ler_bitmap(img, &t);

if(bmp == NULL){
printf("Falha ao ler bitmap.\n");
return 0;
}

printf("Bitmap[%s]:\n", IMAGEM);
printf("=-=-=BITMAP ARQUIVO CABECALHO=-=-=\n");
printf("Tipo: 0x%x.\n", bmp->bmp_tipo);
printf("Tamanho total do arquivo: %lu bytes.\n", bmp->bmp_tam);
printf("Reservado1(?): %d.\n", bmp->bmp_reservado1);
printf("Reservado2(?): %d.\n", bmp->bmp_reservado2);
printf("Numero de bytes daqui pra frente para acessar o info reader: %lu.\n", bmp->bp_infocab);

printf("=-=-=BITMAP INFO CABECALHO=-=-=\n");
printf("Tamanho da estrutura: %lu bytes.\n", bmp->leitor_tam);
printf("larguraXaltura: %lix%li.\n", bmp->bmp_larg, bmp->bmp_alt);
printf("Numero de planos de cor(?): %d.\n", bmp->bmp_planos_cor);
printf("Bits/Bytes por pixel: %d - %d.\n", bmp->bmp_bpp, bmp->bmp_bpp/8);
printf("Tipo de compressao(?): %lu.\n", bmp->bmp_compressao);
printf("Tamanho da imagem: %lu bytes.\n", bmp->bmp_tam_img);
printf("Numero de pixels por metro em x e y(?): %li - %li.\n", bmp->bmp_x_pxl_por_mtr, bmp->bmp_y_pxl_por_mtr);
printf("Numero de cores usadas: %lu.\n", bmp->bmp_cont_cores);
printf("Numero de cores importantes para o Windows: %lu.\n", bmp->bmp_cont_coresw);

printf("=-=-=PALETA=-=-=\n");
printf("Paleta:\n");
for(i=0; i < 257; i++)
printf("0x%x ", bmp->paleta[i]);
puts("\n");

printf("=-=-=DADOS=-=-=\n");
for(i=0; i < t; i++)
printf("0x%x ", bmp->dados[i]);

liberar_bitmap(bmp);

return 0;
}

struct bitmap* ler_bitmap(FILE* arquivo, int* tdados)
{
int tcab=sizeof(struct bitmap)-sizeof(void*);
struct bitmap* bmp = (struct bitmap*)malloc(sizeof(struct bitmap));

if(bmp == NULL)
return NULL;

fread(bmp, tcab, 1, arquivo);//Lendo conteúdo do cabeçalho

//Quantidade de bytes nos dados
fseek(arquivo, 0, SEEK_END);
*tdados = ftell(arquivo) - tcab;

//Até 4 bytes por pixels(32 bits)
bmp->dados = (unsigned*)malloc(4*(*tdados));

if(bmp->dados == NULL)
return NULL;

//Posiciona no ponto de leitura
fseek(arquivo, tcab, SEEK_SET);
//Ler os dados
fread(bmp->dados, *tdados, 1, arquivo);

return bmp;
}

void liberar_bitmap(struct bitmap* bmp)
{
free(bmp->dados);
free(bmp);
}


alguns dados parecem corretos como por exemplo o tipo de bitmap, mas não tenho certeza se está tudo correto pois alguns dados parecem ter valores estranhos, por exemplo:

número de cores usada e número de cores usada(zero) importantes para o windows(mais de 20 mil)

na parte dos dados eu li alguns dados que e procurei o código das cores na internet e percebi que alguns números formavam realmente a cor da imagem(formada por apenas uma cor), grande parte dos dados é mostrada como zero e o programa não travou então acho que não usei muita memória não reservada, mas a quantidade de zeros é muito grande.

Essas coisas me deixaram na dúvida sobre o programa funcionar corretamente, então vim aqui pedi ajuda a alguém com mais experiência, v se está de acordo com o padrão bitmap e se os resultados são os normais mesmo.

Agradeço a quem ajudar.


  


2. Re: Lendo bitmap

???
gokernel

(usa Linux Mint)

Enviado em 18/07/2013 - 06:24h

Se quer poupar tempo/trabalho para algo simples use a SDL com seu bitmap(SDL_Surface*) ...

Se quer realmente aprender ler/escrever/desenhar sobre bitmap, pegar o codigo aqui ( www.libsdl.org ) ... e lembrando que o código da SDL não é legível. ;)

E lembrando que bitmap tem padrão de cores em: 8, 16, 24, 32 bits.






Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts