Asuntos Oficiales > Retos
Formato Bmp
Nagisa:
A mi me parecio mucho mas facil leer byte a byte, aunque que el alineado sea a 32 bits te inita a que leas por palabras...
Danielo:
Gracias Geo y Nagisa...
He logrado disminuir un poco (al menos por el momento) el problema cambiando la estructura de la matriz de bits, porque por lo visto la que estaba utilizando:
--- Código: Text ---struct TMatriz{ COLORREF **coords; int maxX,maxY; }; en el momento de crearla consumía mucha memoria y se desbordaba. Asi que de no muy buena gana ahora estoy con una matriz estática:
--- Código: Text ---DWORD matriz[MAXLARGO][MAXANCHO*3]; y ahora al menos puedo cargar el bmp en pantalla, pero sigo teniendo el problema de que cuando lo muestro se ve en rojo y negro.
--- Citar --- ¿Y cómo realizas la lectura de tu matriz de colores?
--- Fin de la cita ---
Todo esta apuntando a que no estoy leyendo bien la matriz, pero no logro darme cuenta, el código lo he escrito según lo que he leido y he entendido en este foro y lo adjunto, en una de esas alguien ve algo que yo no veo:
--- Código: Text ---int alto=getAltoBitmap(bmp); int ancho=getAnchoBitmap(bmp); int x,y; DWORD tmpByte; int bytesRelleno = (bool)((getAnchoBitmap(bmp)*3) % 4) * (4 - ((getAnchoBitmap(bmp)*3) % 4)); fseek(arch, getNumBytesHastaPixel(bmp), SEEK_SET); for(y=alto; y > 0; y--) { for(x = 0; x < ancho*3; x++) cargarMatrizBMP(y-1,x,fgetc(arch),bmp); for(x = 0; x < bytesRelleno; x++) tmpByte = fgetc(arch); }
... y la función CargarMatrizBMP:
--- Código: Text ---void cargarMatrizBMP(int x,int y, DWORD valor,imagenBMP *bmp){ bmp->matriz[x][y]=valor;}
Geo:
El primer ciclo for es muy probable que te cause problemas, pues si tu matriz es [alto][ancho], el indice de la última fila es alto - 1, y tú estás tratando de acceder a la última fila con el índice alto.
--- Código: Text --- for(y=alto; y > 0; y--) { for(x = 0; x < ancho*3; x++) cargarMatrizBMP(y-1,x,fgetc(arch),bmp); for(x = 0; x < bytesRelleno; x++) tmpByte = fgetc(arch); }
Como lo pones, me parece que estás guardando cada componente de color (1 byte) en un COLORREF (dword, 4 bytes), lo cual me parece un desperdicio pues bien podrías guardar las tres componentes de un pixel en un COLORREF.
Porque, ahora habría que ver cómo estás pintando la matriz al HDC :P. Lo más probable es que estés pintando solo rojo porque sólo estás estableciendo la componente roja de tus COLORREF :).
Tal como está tu código, creo que tu matriz podría ser de unsigned chars[ alto ] [ ancho * 3 ] y pintarla así:
--- Código: Text --- unsigned char azul;unsigned char verde;unsigned char rojo;COLORREF color;for ( y = 0; y < alto; y++ ) { for( x = 0; x < ancho; x++ ) { azul = matriz[ y ] [ x * 3 ]; verde = matriz[ y ] [ x * 3 + 1 ]; rojo = matriz[ y ] [ x * 3 + 2 ]; color = RGB( rojo, verde, azul ); SetRGB( hdc, x, y, color ); }}
Otra opción podría ser que tu matriz fuera de COLORREF[ alto ][ ancho ] y llenarla con algo como esto:
--- Código: Text --- unsigned char azul; unsigned char verde; unsigned char rojo; for ( y = alto - 1; y >= 0; y-- ) { for ( x = 0; x < ancho; x++ ) { // Por cada punto leemos tres bytes (las tres componentes BGR) azul = fgetc( arch ); verde = fgetc( arch ); rojo = fgetc( arch ); matriz[ y ][ x ] = RGB( rojo, verde, azul ); } // Para cada línea saltamos los bytes de relleno for ( z = 0; z < bytesRelleno; z++ ) { tmpByte = fgetc( arch ); } }
Así, guardas cada pixel (las tres componentes, 3 bytes) en un solo COLORREF que luego podrías pintar más fácilmente :).
--- Código: Text --- for ( y = 0... for ( x = 0; x < ancho; x++ ) SetPixel( hdc, x, y, matriz[ y ][ x ];
Saludos,
JJ (Geo).
inforsystem:
--- Cita de: "Nagisa" ---
--- Citar ---bitsize = (ancho_imagen * ((bpp + 7) / 8) * abs(alto_imagen);
--- Fin de la cita ---
Por lo que parece, lo que hace es alinear a bytes el numero de bits por pixel para ver cuantos hay que leer, no?? De todas formas, ¿donde va exactamente el parentesis que falta? :alien:
--- Fin de la cita ---
Hola
Perdon por el error, la funcion es asi:
bitsize = (ancho_imagen) * ((bpp + 7) / 8) * abs(alto_imagen);
Pero eso no es todo, me olvide de decirles cuando se debe utilizar:
Cuando la variable bmiSizeImage de la estructura BITMAPINFOHEADER es igual a 0(cero).
Esto es utilil cuando quieren guardar una imagen al disco.
if((bitsize = (*info)->header.bmiSizeImage) == 0)
{
bitsize = (ancho_imagen * ((bpp + 7) / 8) * abs(alto_imagen);
};
Lamento no participar, pero mi "maquina" esta a 148km de distancia :huh: , por eso tambien debo pedir disculpas por mis errores, pero aveces mi memoria me falla( como seguro podran observar en el codigo que les di ahora :hola: )
Tengo el codigo(lapiz y papel) para imprimir los mapas de bits y para guardarlo al disco.No lo publico porque no se si lo quieren realizar en un nuevo reto...
Saludos a todos y tratare de no participar tanto si no estoy bien seguro de la teoria al menos. :hola:
inforsystem:
--- Cita de: "Nagisa" --- A mi me parecio mucho mas facil leer byte a byte, aunque que el alineado sea a 32 bits te inita a que leas por palabras...
--- Fin de la cita ---
Hola.
Si utilizas la funcion fread, no creo que leer byte a byte sea lo mas optimo.
La estructura de un archivo bmp(puede que lo sepas) es asi:
----BITMAPINFOHEADER---
----BITMAPINFO-------------
----MAPA DE BITS----------
Para cuando el "cursor" de posicion este en el final de la estructura BITMAPINFO ya tienes suficientes datos para leer el contenido completo del mapa de bits.
VOID *bits;
...
bits = (VOID*) malloc(bitsize);
fread(bits,1,bitsize,fp); //Se lee de una vez
...
No crees que es más optimo cargar a memoria y luego leer los datos de ahi, que hacer sucesibas peticiones de lectura al disco?
Saludos
Navegación
[#] Página Siguiente
[*] Página Anterior
Ir a la versión completa