C/Visual C - Problemas con la lectura del BMP

 
Vista:

Problemas con la lectura del BMP

Publicado por jose (18 intervenciones) el 13/10/2002 22:26:19
Esto es lo que he sacado en claro, mas bien poco, no se ni la cabecera que hay que meter, y lo que he puesto en astericos tampoco, me parece que me falta una estructura que es el BMPINFO, donde vienen los datos como el tamaño, el numero de lineas, etc... si podeis echarme otra manita, por favor. Gracias.

#include <stdio.h>

void main (void)
{
HDC hdc;
HDC dialogo;
HANDLE hBitmap;
BITMAP bmp;
hdc = CreateCompatibleDC(hDcDialogo); HdcDialogo se supone que es NULL, no?


hBitmap = LoadImage(hBitmap, "prueba.BMP", Image_Bitmap, 0, 0, LR_MONOCHROME);
SelectObject(hdc, hBitmap);

char *buff;

GetObject(hBitmap, *****, buff);


int dimensiones = ********;
buff = (char *)malloc(dimensiones);
if (GetDIBits(hdc, hBitmap, 1, ***, buff, bmp, DIB_RGB_COLORS) ¡= dimensiones)
{
printf ("ERROR\n");
}
else
{

//En que estructura tengo los pixels??

}


}
Valora esta pregunta
Me gusta: Está pregunta es útil y esta claraNo me gusta: Está pregunta no esta clara o no es útil
0
Responder

RE:Problemas con la lectura del BMP

Publicado por Alvaro (122 intervenciones) el 14/10/2002 17:24:43
Ok.
El hdcDialogo es el HDC (Handle of Device Content) de la ventana en la que estas trabajando. Veo que estas trabajando en una aplicacion win32 tipo consola, por lo que no tienes dialogos.
CreateCompatibleDC es utilizado para crear un HDC compatible con otro que ya este cargado. (hdcdialogo no es NULL)
Puedes reemplazarlo po el hdc de la pantalla, eso lo obtienes con CreateDC("DISPLAY", NULL, NULL, NULL);
En LoadImage estas especificando el nombre de un archivo en vez de un recurso de la aplicación, por esto debes poner el especificador LR_LOADFROMFILE ( con un 'o' logico ) en el ultimo parámetro.

Para el GetObject debes pasar hBitmap, sizeof(BITMAP), &bmp como parametos para obtener en bmp informacion necesaria para utilizar GetDIBits.

Debes definir una estructura del tipo BITMAPINFO que llenaras con ceros ( con memset ) y setearás solo algunos valores, como por ejemplo, biSize debe ser seteado a sizeof(BITMAPIMFO). biPlanes = 1. etc.

La funcion GetDIBits te retorna en buff los bytes del bitmap.
en el BITMAPINFOHEADER contenido en el BITMAPINFO aparecen las dimenciones del bitmap (numero de scanlines, pixels horizontales y verticales, etc.) pero lo mas importande de eso es la cantidad de bits por pixel.
segun eso tu veras como recorrer el buffer.
( Ojo, si el bitmap es monocromatico es un 'bit' por pixel ).

SUERTE...
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

RE:Problemas con la lectura del BMP

Publicado por jose (18 intervenciones) el 14/10/2002 17:49:16
Oye tio te voy a poner un monumento, voy a probar eso ahora mismo, ahora te cuento. GRACIASSSSSSSSSSSSSSSSSSSSSSSSSSSS
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

AYUDA ALVARO!!!!!!!!!

Publicado por jose (18 intervenciones) el 14/10/2002 18:10:53
Me falla en el GetDIBits, no se me llena la estructura INFO, esta llena con ceros, porqué puede ser? Yo creo que estan bien los parametros, tuve que hacer un casting al HBitmap porque me lo pedia.

#include <stdio.h>
#include <windows.h>
#include <wingdi.h>

void main (void)
{
HDC hdc;
HANDLE hBitmap;
BITMAP bmp;
int dimensiones;
hdc=CreateDC("DISPLAY", NULL, NULL, NULL);

hBitmap = (HBITMAP)LoadImage (NULL, "prueba1.BMP", IMAGE_BITMAP, 0, 0, 0);
SelectObject(hdc, hBitmap);

char *buff;

GetObject(hBitmap, sizeof(BITMAP), &bmp);


dimensiones = (bmp.bmHeight * bmp.bmWidth);
buff = (char *)malloc(dimensiones);

int altura = bmp.bmHeight;
int ancho = bmp.bmWidth;
int bitper = bmp.bmBitsPixel;
int widhtbyte = bmp.bmWidthBytes;
int panels = bmp.bmPlanes;


BITMAPINFO info;
memset(&info, 0, sizeof(BITMAPINFO));
info.bmiHeader.biPlanes=1;
info.bmiHeader.biSize=sizeof(info);

int res=GetDIBits(hdc, (HBITMAP)hBitmap, 1, altura, buff, &info, DIB_RGB_COLORS);
if (res==0)
{
printf ("fallo en el GetDIBits");
}
if (info.bmiHeader.biBitCount==1)
{
//Leo de 1 en 1 el contenido de buff;

}
}
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

RE:AYUDA ALVARO!!!!!!!!!

Publicado por Alvaro (122 intervenciones) el 14/10/2002 19:37:36
Ok.
En LoadImage usa el primer parámetro como el resultado de GetModuleHandle(NULL)
El Ultimo parámetro debe ser LR_LOADFROMFILE | LR_MONOCHROME.
Si tienes el hBitmap cargado será distinto de NULL, valida eso.
Ok.
Si tienes problemas con GetDIBits puedes pasarle primero el buffer a NULL. Así se llenará la estructura INFO con los datos del bitmap.
Si todo esto no resulta, puedes obtener los bits utilizando GetPixel)hdcBitmap, x, y);
esta te obtiene un pixel, por lo que debes hacer un ciclo para asignarlos al buffer.
for (i = 0; i < height; i++) {
for(j = 0; j < width; j++) {
buffer[width * i + j] = GetPixel(hdcBitmap, j, i);
}
}

Suerte...
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

RE:AYUDA ALVARO!!!!!!!!!

Publicado por jose (18 intervenciones) el 14/10/2002 20:45:18
Vale, he llamado a GetDIBits con el parametro a NULL, entonces ahora para llenar el buffer hago otra vez la llamada no?
Es que el problema esta en el buffer, no se si declararlo como puntero o no?, pero claro entonces no se que tamaño darle, he hecho esto, y despues al leer el buffer me da resultados raros por pantalla, no se si lo estare leyendo mal:

char buffer[1024];
res=GetDIBits(hdc, (HBITMAP)hBitmap, 1, altura, buffer, &info, DIB_RGB_COLORS);
if (res==0)
{
printf ("fallo en el GetDIBits");
}
else
{
//He puesto un bucle aleatorio en cuanto al limite, no se cual es
char x;
for (int k=0; k<=200; k++)
{
x= buffer[k];
printf ("%c",x);
}
}
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

RE:AYUDA ALVARO!!!!!!!!!

Publicado por Alvaro (122 intervenciones) el 14/10/2002 22:17:56
Intenta lo siguiente:
declara un int *buffer;
Carga la estructura BITMAP bmp con el GetObject(hdcBitmap, sizeof(BITMAP), &bmp);
bmp ahora contiene la información necesaria.
el alto y ancho del bitmap estan en bmp (en pixels).
Tu imagen es monocromatica por lo que cada pixel necesita un bit para ser cargado (blanco = 1, negro = 0)
el tamaño del buffer necesario para cargar los bist es:
largo_buffer = alto (en pixels) * ancho (en pixels) / 8 (pixels en un byte).
Si tu imagen no es monocromatica (de 32 bits por pixel, por ejemplo) el tamaño del buffer esta dado por:
largo_buffer = alto * ancho * 4. (o sizeof(int))
El alto y ancho los sacas de la variable bmp.
ahora puedes hacer un malloc(largo_buffer).
Bien. Si usas GetDIBits los obtendras todos de una sola vez, pero para obtener un pixel especifico desde el buffer deberas obtener el byte en el que está y hacer los shift (>>) necesarios para obtener un solo bit (recuerda que es monocromatico).
Si utilizas (por el contrario) GetPixel(hdcBitmap, x, y) ontendras una variable entera con valor 0 o 1.
Así que mejor declaras el buffer de la segunda forma (alto * ancho * 4) y efectuas el bucle que te mostre en la otra nota para llenarlo.
Esto te ha tenido ocupado ¿no?.
Si lo logras con GetDIBits me lo cuentas.
La desbentaja de GetPixel es que es una funcion antigua, y Microsoft aconseja no utilizarla por eso, supongo que no la utilizaran mas en nuevas versiones de Windows.
SUERTE...
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

RE:AYUDA ALVARO!!!!!!!!!

Publicado por jose (18 intervenciones) el 15/10/2002 15:54:50
Mira lo he intentado con el getPixel, y despues le he ehcho un recorrido al buffer para mostrarlo en pantalla, pero todos los datos que devuelve getPixel eran -1 , en vez de devolver 1 y 0´s, no se donde esta el fallo, lo que me pusiste de HdcBitmap en la llamada a GetPixel es el Handle del Bitmap que cogo con select Object, no?, no se si sera por eso, o es que el buffer no está bien:

********************************************************************************

int res=GetDIBits(hdc, (HBITMAP)hBitmap, 1, altura, NULL, &info, DIB_RGB_COLORS);
if (res==0)
{
printf ("fallo en el GetDIBits");
}
if (info.bmiHeader.biBitCount==1)
{
printf ("\nHay un bit por pixel");
}

int *buffer2;
long largo = altura * ancho /4;
buffer2 = (int *)malloc(largo);

for (int i = 0; i < altura; i++)
{
for(int j = 0; j < ancho; j++)
{
buffer2[ancho*i + j] = GetPixel(HDC(hBitmap), j, i);
}
}
//Ya tengo lleno el buffer con todos los bits

int x;
for (int k=0; k<64; k++)
{
x= buffer2[k];
printf ("%d",x);
}
***************************************************************************

Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

RE:AYUDA ALVARO!!!!!!!!!

Publicado por Alvaro (122 intervenciones) el 15/10/2002 16:43:06
Ok...
Te mando un ejemplo...
Suerte...
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar