Asuntos Oficiales > Retos

 Formato Bmp

<< < (22/35) > >>

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 &#62; 0; y--) {   for(x = 0; x &#60; ancho*3; x++)        cargarMatrizBMP(y-1,x,fgetc(arch),bmp);    for(x = 0; x &#60; bytesRelleno; x++)            tmpByte = fgetc(arch);     }  
... y la función CargarMatrizBMP:

--- Código: Text ---void cargarMatrizBMP(int x,int y, DWORD valor,imagenBMP *bmp){  bmp-&#62;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 &#62; 0; y--) {  for(x = 0; x &#60; ancho*3; x++)       cargarMatrizBMP(y-1,x,fgetc(arch),bmp);   for(x = 0; x &#60; 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 &#60; alto; y++ ) {  for( x = 0; x &#60; 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 &#62;= 0; y-- ) {    for ( x = 0; x &#60; 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 &#60; 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 &#60; 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

[0] Índice de Mensajes

[#] Página Siguiente

[*] Página Anterior

Ir a la versión completa