Ver Mensaje Individual
  #2 (permalink)  
Antiguo 30/01/2012, 02:07
Fw190
 
Fecha de Ingreso: junio-2010
Ubicación: Madrid
Mensajes: 620
Antigüedad: 14 años, 5 meses
Puntos: 73
Respuesta: Problemilla sobre imagenes BMP en c++

Un archivo de imagen, en formato BMP, tiene una cabecera que contiene la información acerca de la imagen (tamaño, colores, etc), seguida de los valores de la imagen, pixel a pixel. La estructura de esta cabecera es:

Cabecera (14 bytes):
Firma (2 bytes) Siempre 'BM'
Tamaño del archivo (4 bytes) Tamaño del archivo, en bytes
Reservado (4 bytes) Siempre cero
Offset de datos (4 bytes) Offset a comienzo de datos

Cabecera de información (40 bytes)
Tamaño (4 bytes) Tamaño de la cabecera de información
Anchura (4 bytes) Anchura del bitmap en pixels
Altura (4 bytes) Altura del bitmap en pixels
Planos (2 bytes) Número de planos (siempre 1)
Bits por pixel (2 bytes) Valores válidos: 1, 2, 4, 8, 24, 32
Compresión (4 bytes) Tipo de compresión (0 = No)
Tamaño de imagen (4 bytes) Tamaño de la imagen (comprimida en su caso)
X-pixels (4 bytes) Resolución horizontal
Y-pixels (4 bytes) Resolución vertical
Colores usados (4 bytes) Número de colores utilizados
Colores importantes (4 bytes) Número de colores importantes (0 = todos)

Tabla de colores (4*NumColores bytes)
Sólo habrá tabla de colores si BitsPorPixel<=8, si es 24 ó 32 no hay tabla de colores y se pasa directamente a los datos.

Rojo 1 byte
Verde 1 byte
Azul 1 byte
Reservado 1 byte (siempre cero)
(esto se repetiría NumColores veces)

Datos (Tamaño_de_imagen bytes)

(confírmalo buscando en Internet). Los datos de la imagen vienen por orden, aunque en este momento no recuerdo si comienza por la esquina superior izquierda o inferior izquierda.

Si la imagen se guardó con 24 bits de color, para cada pixel tendrás 3 bytes, uno para rojo (R), otro para verde (G) y otro para azul (B), de este modo:

RRGGBB RRGGBB RRGGBB (etc)

(bueno, no recuerdo si aparecen así o aparecen BBGGRR) donde cada secuencia RRGGBB representa 1 pixel.

Si la imagen se guardó con 32 bits de color, a cada pixel le corresponde un entero de 32 bits (4 bytes). El número de colores es el mismo, simplemente se guarda un byte adicional que es siempre cero. En los cuatro bytes de ese entero (que corresponde a un pixel) vas a tener

00 RR GG BB

(aquí sí estoy seguro del orden), es decir, el primer byte es siempre 0, el segundo corresponde al rojo, el tercero al verde y el último al azul.

Convendría que te hicieras con un editor hexadecimal y que abrieras con él el archivo de imagen, así podrás ver "de primera mano" la cabecera del archivo y los datos, esto te ayudará.

Un último detalle si utilizas el editor hexadecimal o tu programa va a leer el archivo byte por byte: Los procesadores INTEL guardan los números (sean del tipo que sean) comenzando por el byte menos significativo (se denomina formato little-endian), por ejemplo, el entero que me guarda la información del pixel, que sería 00 RR GG BB, estará almacenado como BB GG RR 00 (lo puedes ver con el editor hexadecimal).

Solución a tu problema:

Primero: Si coges una foto y la rotas (imagino que se refiere a 90º), ¿Cómo queda la imagen? Fíjate en que la última "línea" de abajo pasaría a ser la primera "columna" de la izquierda, etc.

Segundo: Ya tienes la estructura de la cabecera. Simplemente, haz un programa que lea esa cabecera y presente la información que desees.

Tercero: Los tonos de gris se obtienen con las tres componentes de color iguales, tendrás 256 tonos de gris (desde R=G=B=0, negro, hasta R=G=B=255, blanco brillante). Para pasar de color a gris, tendrás que buscarte algún algoritmo de conversión concreto, eso tendrás que buscar por Internet y decidir con cuál de los que ensayes te queda mejor la imagen.

Lo de ser malísimo en C++ (o cualquier otro lenguaje de programación) suele arreglarse dándole a la tecla. Si tienes problemas postea lo que tengas, pero no esperes que te hagan la tarea.

Saludos,