Como obter um bitmap puro? [RESOLVIDO]

Galera, alguem sabe como posso converter uma imagem para formato BITMAP PURO?? Eu estou desenvolvendo uma aplicação em C ANSI, para um processador especifico. Lá contem uma função que exibe na tela um bitmap, puro. Eu tentei criar um bitmap monocromatico no PAINT e enviar ele para aplicacao cliente, porem me parece que o bitmap gerado pelo paint não é puro, contem descritor do arquivo, etc. Queria saber se alguem conhecer uma aplicação, ou ate API do java, para converter uma imagem em bitmap puro, ou, que de para mim desenhar e salvar em bitmap puro. Obrigado

Imagem Bitmap puro não é uma imagem com a matriz de pixels onde os valores são somente RGB e variam entre 0 e 255?

Creio que sim, olhe um dos exemplos que tem na aplicacao aqui:

byte bmp[] = {0xFF, 0xF0, 0x00, 0xCC, 0x3C, 0x3C, 0xCC, 0x00, 0xF0,0xFF, 0xFF, 0xF0, 0x00, 0xCC, 0x3C, 0x3C, 0xCC, 0x00, 0xF0,0xFF, 0xFF, 0xF0, 0x00, 0xCC, 0x3C, 0x3C, 0xCC, 0x00, 0xF0,0xFF, 0xFF, 0xF0, 0x00, 0xCC, 0x3C, 0x3C, 0xCC, 0x00, 0xF0,0xFF, 0xFF, 0xF0, 0x00, 0xCC, 0x3C, 0x3C, 0xCC, 0x00, 0xF0,0xFF, 0xFF, 0xF0, 0x00, 0xCC, 0x3C, 0x3C, 0xCC, 0x00, 0xF0,0xFF, 0xFF, 0xF0, 0x00, 0xCC, 0x3C, 0x3C, 0xCC, 0x00, 0xF0,0xFF, 0xFF, 0xF0, 0x00, 0xCC, 0x3C, 0x3C, 0xCC, 0x00, 0xF0,0xFF, 0xFF, 0xF0, 0x00, 0xCC, 0x3C, 0x3C, 0xCC, 0x00, 0xF0,0xFF, 0xFF, 0xF0, 0x00, 0xCC, 0x3C, 0x3C, 0xCC, 0x00, 0xF0,0xFF, 0xFF, 0xF0, 0x00, 0xCC, 0x3C, 0x3C, 0xCC, 0x00, 0xF0,0xFF, 0xFF, 0xF0, 0x00, 0xCC, 0x3C, 0x3C, 0xCC, 0x00, 0xF0,0xFF, 0xFF, 0xF0, 0x00, 0xCC, 0x3C, 0x3C, 0xCC, 0x00, 0xF0,0xFF, 0xFF, 0xF0, 0x00, 0xCC, 0x3C, 0x3C, 0xCC, 0x00, 0xF0,0xFF, 0xFF, 0xF0, 0x00, 0xCC, 0x3C, 0x3C, 0xCC, 0x00, 0xF0,0xFF, 0xFF, 0xF0, 0x00, 0xCC, 0x3C, 0x3C, 0xCC, 0x00, 0xF0,0xFF, 0xFF, 0xF0, 0x00, 0xCC, 0x3C, 0x3C, 0xCC, 0x00, 0xF0,0xFF, 0xFF, 0xF0, 0x00, 0xCC, 0x3C, 0x3C, 0xCC, 0x00, 0xF0,0xFF, 0xFF, 0xF0, 0x00, 0xCC, 0x3C, 0x3C, 0xCC, 0x00, 0xF0,0xFF, 0xFF, 0xF0, 0x00, 0xCC, 0x3C, 0x3C, 0xCC, 0x00, 0xF0,0xFF };

Seria uma matriz de pixel mesmo. O que quero saber eh como posso desenhar uma imagem, e transforma-la nisso. Abraços

Se vc kiser fazer isso na mão, acho que tem um método para pegar a cor de um pizel na tela. Aí basta fazer a matriz apropriada…

A imagem tem que ser um dib, sem nenhum tipo de compressão.( alguns .bmp tmb podem estar codificados com algum algoritmo)

leia essas referências
http://www.herdsoft.com/ti/davincie/imex3j8i.htm
http://www.fortunecity.com/skyscraper/windows/364/bmsinwin.html

Vc pode tmb usar um algoritmo referente ao modelo de compressão que está gerando o bitmap para descompactá-lo, em seu soft c ansi. Sendo assim poderá exibí-lo tmb.

http://homepages.inf.ed.ac.uk/rbf/HIPR2/

Essa refeência tem algoritmos de compressão, e tem seus exemplos feitos em java, mas vc pode adaptá-los sem problema para c++ ou c.

Em Java você pega o RGB de um pixel usando Rasters, SampleModels, DataBuffers. Na verdade, é só a chamada de um método (ImageIO.read(new File(nomeImagem)).getRGB()) e a conversão para as três cores (int r = 0x00FF0000>>>16, 8 e nada, variando a posição dos FF).

Em C eu não tenho idéia de como faz, mas acredito que deva existir alguma lib pronta pra lidar com imagens. Eu conheço duas: CImg e OpenCV.

Sinto não poder ajudar mais.
Abraço.

Ele quer escrever o código. Lib tem várias(como a CxImage e a OpenCV da intel(essa é fodassa)). Pega a documentação do header da windows.h, que te mostra como faz de boa. Num tem segredo não;]

Galera, estamos quase lá. Na verdade eu nao quero fazer esse tipo de manipulacao em C. Pode ser em C ou Java. Como disse, é uma aplicacao Cliente/Servidor. O servidor é java, o cliente é C. O que preciso eh que esteja em bitmap puro em C, pode ser processado em java e ja enviar pronto, ou enviar e ser processado em C. Mais acredito que processar em java é mais facil.

Andre, me parece que a sua solução é a ideal. porem o getRGB pede um int x e int y, que acredito ser o Width e Heigth da imagem. Certo, o que ele me retorna eh um inteiro estranho, veja:

-16777216 -16777216 -16777216 -16777216 …

esses valores provavelmente representa acor preta, q eh a mais predominante na imagem que to processando.

A aplicação que estou desenvolvendo precisa de um bitmap puro. Ela vai imprimir apenas preto ou nada. Ou seja, bit 1 representa um pixel preto, bit 0 representa nada(branco). Entao o que preciso fazer na verdade é pegar os pixels da imagem e verificar: se for branco, 0, se for qualquer outra cor, 1. Entende?

Por exemplo: 0xFF = 255 = 11111111

Isso significa que tem 8 pixels ligados, isso daria uma linha reta ______ na minha aplicacao :slight_smile:

Aguardo uma posição. Abraços e obrigado

[quote=juliocbq]A imagem tem que ser um dib, sem nenhum tipo de compressão.( alguns .bmp tmb podem estar codificados com algum algoritmo)

leia essas referências
http://www.herdsoft.com/ti/davincie/imex3j8i.htm
http://www.fortunecity.com/skyscraper/windows/364/bmsinwin.html

Vc pode tmb usar um algoritmo referente ao modelo de compressão que está gerando o bitmap para descompactá-lo, em seu soft c ansi. Sendo assim poderá exibí-lo tmb.

http://homepages.inf.ed.ac.uk/rbf/HIPR2/

Essa refeência tem algoritmos de compressão, e tem seus exemplos feitos em java, mas vc pode adaptá-los sem problema para c++ ou c.[/quote]

Julio, essa forma que vc esta me falando parece a forma dificil, que seria descomprimir a imagem e pegar seu conteudo original, acredito que em java de para processar os pixels em individual sem precisar essa manobra toda. Abraços

Use libpng e boa sorte.

[quote=mizael86][quote=juliocbq]A imagem tem que ser um dib, sem nenhum tipo de compressão.( alguns .bmp tmb podem estar codificados com algum algoritmo)

leia essas referências
http://www.herdsoft.com/ti/davincie/imex3j8i.htm
http://www.fortunecity.com/skyscraper/windows/364/bmsinwin.html

Vc pode tmb usar um algoritmo referente ao modelo de compressão que está gerando o bitmap para descompactá-lo, em seu soft c ansi. Sendo assim poderá exibí-lo tmb.

http://homepages.inf.ed.ac.uk/rbf/HIPR2/

Essa refeência tem algoritmos de compressão, e tem seus exemplos feitos em java, mas vc pode adaptá-los sem problema para c++ ou c.[/quote]

Julio, essa forma que vc esta me falando parece a forma dificil, que seria descomprimir a imagem e pegar seu conteudo original, acredito que em java de para processar os pixels em individual sem precisar essa manobra toda. Abraços[/quote]

O hipr já está implementado, vc não vai precisar escrever nada se vc não quiser. Tem exemplos em applets lá;

[quote=mizael86]Galera, estamos quase lá. Na verdade eu nao quero fazer esse tipo de manipulacao em C. Pode ser em C ou Java. Como disse, é uma aplicacao Cliente/Servidor. O servidor é java, o cliente é C. O que preciso eh que esteja em bitmap puro em C, pode ser processado em java e ja enviar pronto, ou enviar e ser processado em C. Mais acredito que processar em java é mais facil.

A aplicação que estou desenvolvendo precisa de um bitmap puro. Ela vai imprimir apenas preto ou nada. Ou seja, bit 1 representa um pixel preto, bit 0 representa nada(branco). Entao o que preciso fazer na verdade é pegar os pixels da imagem e verificar: se for branco, 0, se for qualquer outra cor, 1. Entende?

Por exemplo: 0xFF = 255 = 11111111

Isso significa que tem 8 pixels ligados, isso daria uma linha reta ______ na minha aplicacao :slight_smile:

Aguardo uma posição. Abraços e obrigado[/quote]

O que vc quer fazer se chama limiarização de uma imagem digital. O primeiro passo é criar um bitmap de 8bpp(Esse bitmap possui apenas um byte, ou seja, uma banda de cor). Vc vai pegar o conteúdo original e converte-lo em escala de cinza, depois aplicar a função limiar(como vc disse, se um pixel maior que 128, recebe 1, menor, recebe 0). O exemplo disso é:

Algoritmo explicação:
http://homepages.inf.ed.ac.uk/rbf/HIPR2/threshld.htm

E como eu disse: A implementação em java, como applet
http://homepages.inf.ed.ac.uk/rbf/HIPR2/threshdemo.htm

Galera consegui resolver de uma forma bem simples, segue o codigo.

[code]ByteArrayOutputStream baos = new ByteArrayOutputStream();

	BufferedImage imag = ImageIO.read(new File("C:\teste.bmp"));
				
	// 1 - 2 - 4 - 8 - 16 - 32 - 64 - 128
	
	byte valor = 0;
	
	int posBit = 8;
	
	for (int y = 0; y < imag.getHeight(); y++) {
		for (int x = 0; x < imag.getWidth(); x++) {			
			Color c = new Color(imag.getRGB(x, y));
			
			posBit--;

			if (!(c.getRed() == 255 && c.getBlue() == 255 && c.getGreen() == 255)) {
				valor += Math.pow(2, posBit);
			}
			
			if (posBit == 0) {
				posBit = 8;
				
				baos.write(new byte[]{valor});
				
				valor = 0;
			}
			
		}
	}
	
	if (posBit != 8) {
		baos.write(new byte[]{valor});
	}
	
	byte[] bytes = baos.toByteArray();[/code]

Eu pego o RGB de cada pixel e verifico se sua tonalidade é diferente da cor branca, e ligo o bit de um byte. Se a cor for branca, mantem o bit desligado. Quando ja processei os 8 bits de um byte, e gravo esse byte e processo um outro bit. Eu trabalho com POS, e a impressao dele é monocromatica, entao o bit 1 representa um pixel preto, e 0, 1 pixel vazio. Dessa forma eu consigo transformar qualquer imagem baseada em bitmap em um Raw Bitmap. Obrigado pela força de todos. Abraços

O seu bitmap ainda possui 3bytes. Vc tem que suprimir os outros 2 bytes para obter uma imagem de 8bits realmente.

Nao entendi o que vc quis dizer julio, pelo menos dessa forma ate agora funcionou como eu queria. Mais o que vc quis dizer com tem 3 bytes?

Para ter uma imagem binarizada, precisa reduzi-la a uma imagem de 1byte. Da maneira que está, seus pixels estão setados em 0 ou 1, mas a imagem ainda possui as 3 bandas de cor(3 bytes = 24 bits). É preciso reduzí-la para um byte;