Visualizando imagen en niveles de gris

03/07/2004 - 00:07 por Willser F. González C. | Informe spam
Hola Grupo,

Tengo un archivo tipo RAW (plano), que contiene una imagen de 416 x 416 en
niveles de gris (8 bits por pixel) y estoy intentando mostrarla en pantalla,
pero la imagen se visualiza con colores extraños, aunque la imagen sí se
logra reconocer por su forma, pero no por sus colores. Creo que mi error
puede estar en la definición del BITMAPINFO o algo de la paleta de colores,
pero no encuentro alguna explicación al respecto.


CRect l_crCdroImgen;

BITMAPINFO l_biBitmapInfo;

l_biBitmapInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
l_biBitmapInfo.bmiHeader.biWidth = m_sAnchoArchvo; // 416.
l_biBitmapInfo.bmiHeader.biHeight = -m_sAltoArchvo; // 416.
l_biBitmapInfo.bmiHeader.biPlanes = 1;
l_biBitmapInfo.bmiHeader.biBitCount = 8;
l_biBitmapInfo.bmiHeader.biCompression = BI_RGB; // Uncompressed.
Supongo que está bien.
l_biBitmapInfo.bmiHeader.biSizeImage = 0;
l_biBitmapInfo.bmiHeader.biXPelsPerMeter = 0;
l_biBitmapInfo.bmiHeader.biYPelsPerMeter = 0;
l_biBitmapInfo.bmiHeader.biClrUsed = 0;
l_biBitmapInfo.bmiHeader.biClrImportant = 0;

m_csCdroImgen.GetClientRect(l_crCdroImgen); // Reacuadro donde se
muestra la imagen. m_csCdroImgen es tipo Static.

// Con esta función muestro la imagen ajustada a un recuadro, pero no
conserva los colores correctos.

StretchDIBits(m_csCdroImgen.GetWindowDC()->m_hDC, // handle al DC
0, 0,
// origen del destino
l_crCdroImgen.Width(), l_crCdroImgen.Height(), //
ancho y alto del destino
0, 0,
// origen de la fuente
m_sAnchoArchvo,
// ancho fuente
m_sAltoArchvo,
// alto fuente
m_pucImgen,
// dirección del array de bits
&l_biBitmapInfo,
// dirección de BITMAPINFO
DIB_RGB_COLORS, SRCCOPY); //
colores RGB -

Les agradezco cualquier sugerencia al respecto.

Willser F.

Preguntas similare

Leer las respuestas

#1 Miguel
03/07/2004 - 03:42 | Informe spam
"Willser F. González C." escribía:


Hola Grupo,

Tengo un archivo tipo RAW (plano), que contiene una imagen de 416 x 416 en
niveles de gris (8 bits por pixel) y estoy intentando mostrarla en pantalla,
pero la imagen se visualiza con colores extraños, aunque la imagen sí se
logra reconocer por su forma, pero no por sus colores. Creo que mi error
puede estar en la definición del BITMAPINFO o algo de la paleta de colores,
pero no encuentro alguna explicación al respecto.


CRect l_crCdroImgen;

BITMAPINFO l_biBitmapInfo;

l_biBitmapInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
l_biBitmapInfo.bmiHeader.biWidth = m_sAnchoArchvo; // 416.
l_biBitmapInfo.bmiHeader.biHeight = -m_sAltoArchvo; // 416.
l_biBitmapInfo.bmiHeader.biPlanes = 1;
l_biBitmapInfo.bmiHeader.biBitCount = 8;
l_biBitmapInfo.bmiHeader.biCompression = BI_RGB; // Uncompressed.
Supongo que está bien.
l_biBitmapInfo.bmiHeader.biSizeImage = 0;
l_biBitmapInfo.bmiHeader.biXPelsPerMeter = 0;
l_biBitmapInfo.bmiHeader.biYPelsPerMeter = 0;
l_biBitmapInfo.bmiHeader.biClrUsed = 0;
l_biBitmapInfo.bmiHeader.biClrImportant = 0;

m_csCdroImgen.GetClientRect(l_crCdroImgen); // Reacuadro donde se
muestra la imagen. m_csCdroImgen es tipo Static.

// Con esta función muestro la imagen ajustada a un recuadro, pero no
conserva los colores correctos.

StretchDIBits(m_csCdroImgen.GetWindowDC()->m_hDC, // handle al DC
0, 0,
// origen del destino
l_crCdroImgen.Width(), l_crCdroImgen.Height(), //
ancho y alto del destino
0, 0,
// origen de la fuente
m_sAnchoArchvo,
// ancho fuente
m_sAltoArchvo,
// alto fuente
m_pucImgen,
// dirección del array de bits
&l_biBitmapInfo,
// dirección de BITMAPINFO
DIB_RGB_COLORS, SRCCOPY); //
colores RGB -

Les agradezco cualquier sugerencia al respecto.

Willser F.




Pero... ¿está completo el BITMAPINFO? Digo, la paleta dónde está. Los
256 RGBQUADŽs contiguos al BITMAPINFOHEADER, con la escala de grises

{0x00000000, 0x00010101, 0x00020202, ..., 0x00FEFEFE, 0x00FFFFFF};

Da la impresión que la función está levantando 1KB de basura y lo está
interpretando como la paleta que no le estás proveyendo...

Digo, da la impresión.

LPBITMAPINFO bmi = LocalAlloc(LPTR, sizeof(BITMAPINFOHEADER) + \
256 * sizeof(RGBQUAD));

bmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
...
bmi->bmiColors[] = {...};

...

...
LocalFree(bmi);

Saludos

Miguel
Respuesta Responder a este mensaje
#2 Willser F. González C.
06/07/2004 - 20:55 | Informe spam
Gracias Miguel por su valiosa ayuda,

Efectivamente, inicialicé la paleta de colores y la imagen se muestra
correctamente. Ésta es el código por si le sirve a alguien:


int i;

CRect l_crCdroImgen;

BITMAPINFO *l_pbiBitmapInfo = new BITMAPINFO[sizeof(BITMAPINFOHEADER) +
256 * sizeof(RGBQUAD)];


// Iniciliazar la cabecera del BITMAPINFO.

l_pbiBitmapInfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
l_pbiBitmapInfo->bmiHeader.biWidth = m_sAnchoArchvo; // 416.
l_pbiBitmapInfo->bmiHeader.biHeight = -m_sAltoArchvo; // 416.
l_pbiBitmapInfo->bmiHeader.biPlanes = 1;
l_pbiBitmapInfo->bmiHeader.biBitCount = 8;
l_pbiBitmapInfo->bmiHeader.biCompression = BI_RGB; // Uncompressed.
l_pbiBitmapInfo->bmiHeader.biSizeImage = 0;
l_pbiBitmapInfo->bmiHeader.biXPelsPerMeter = 0;
l_pbiBitmapInfo->bmiHeader.biYPelsPerMeter = 0;
l_pbiBitmapInfo->bmiHeader.biClrUsed = 0;
l_pbiBitmapInfo->bmiHeader.biClrImportant = 0;


// Inicializar la paleta de colores del BITMAPINFO.

for (i = 0; i < 256; i++)
{
l_pbiBitmapInfo->bmiColors[i].rgbBlue = i;
l_pbiBitmapInfo->bmiColors[i].rgbGreen = i;
l_pbiBitmapInfo->bmiColors[i].rgbRed = i;
l_pbiBitmapInfo->bmiColors[i].rgbReserved = 0;
}

m_csCdroImgen.GetClientRect(l_crCdroImgen); // Reacuadro.


// Mostrar la imagen ajustada a un recuadro.

StretchDIBits(m_csCdroImgen.GetWindowDC()->m_hDC, // handle al DC.
0, 0, // origen del destino.
l_crCdroImgen.Width(), l_crCdroImgen.Height(), //
Ancho y alto del destino.
0, 0, // Origen de la fuente.
m_sAnchoArchvo, // Ancho fuente.
m_sAltoArchvo, // Alto fuente.
m_pucImgen, // Dirección del array de bits.
l_pbiBitmapInfo, // Dirección de BITMAPINFO.
DIB_RGB_COLORS, SRCCOPY); // Colores RGB.

Tengo una duda adicional que no he podido solucionar a partir de lo
anterior: si la imagen fuera no de 8, sino de 24 bits por pixel, cómo debo
inicializar esta paleta de colores?.

Gracias.

Willser F.
Respuesta Responder a este mensaje
#3 Miguel
06/07/2004 - 22:00 | Informe spam
"Willser F. González C." escribía:


Gracias Miguel por su valiosa ayuda,

Efectivamente, inicialicé la paleta de colores y la imagen se muestra
correctamente. Ésta es el código por si le sirve a alguien:


int i;

CRect l_crCdroImgen;

BITMAPINFO *l_pbiBitmapInfo = new BITMAPINFO[sizeof(BITMAPINFOHEADER) +
256 * sizeof(RGBQUAD)];


// Iniciliazar la cabecera del BITMAPINFO.

l_pbiBitmapInfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
l_pbiBitmapInfo->bmiHeader.biWidth = m_sAnchoArchvo; // 416.
l_pbiBitmapInfo->bmiHeader.biHeight = -m_sAltoArchvo; // 416.
l_pbiBitmapInfo->bmiHeader.biPlanes = 1;
l_pbiBitmapInfo->bmiHeader.biBitCount = 8;
l_pbiBitmapInfo->bmiHeader.biCompression = BI_RGB; // Uncompressed.
l_pbiBitmapInfo->bmiHeader.biSizeImage = 0;
l_pbiBitmapInfo->bmiHeader.biXPelsPerMeter = 0;
l_pbiBitmapInfo->bmiHeader.biYPelsPerMeter = 0;
l_pbiBitmapInfo->bmiHeader.biClrUsed = 0;
l_pbiBitmapInfo->bmiHeader.biClrImportant = 0;


// Inicializar la paleta de colores del BITMAPINFO.

for (i = 0; i < 256; i++)
{
l_pbiBitmapInfo->bmiColors[i].rgbBlue = i;
l_pbiBitmapInfo->bmiColors[i].rgbGreen = i;
l_pbiBitmapInfo->bmiColors[i].rgbRed = i;
l_pbiBitmapInfo->bmiColors[i].rgbReserved = 0;
}

m_csCdroImgen.GetClientRect(l_crCdroImgen); // Reacuadro.


// Mostrar la imagen ajustada a un recuadro.

StretchDIBits(m_csCdroImgen.GetWindowDC()->m_hDC, // handle al DC.
0, 0, // origen del destino.
l_crCdroImgen.Width(), l_crCdroImgen.Height(), //
Ancho y alto del destino.
0, 0, // Origen de la fuente.
m_sAnchoArchvo, // Ancho fuente.
m_sAltoArchvo, // Alto fuente.
m_pucImgen, // Dirección del array de bits.
l_pbiBitmapInfo, // Dirección de BITMAPINFO.
DIB_RGB_COLORS, SRCCOPY); // Colores RGB.




Ok.

Tengo una duda adicional que no he podido solucionar a partir de lo
anterior: si la imagen fuera no de 8, sino de 24 bits por pixel, cómo debo
inicializar esta paleta de colores?.




Si biCompression == BI_BITFIELDS, entonces deberías entregar una
"paleta" de tres entradas. Cada entrada representa una máscara para cada
canal de color. Esto no se aplica a 24 bits, sólo a 16 y 32 bits.

Digamos que tenés un array de 16 bits por pixel, lo habitual sería un
formato 565 (6 pixeles para el verde, por aquello de que el ojo humano
está diseñado para ver mejor el verde), entonces tu tabla de colores
sería {0x0000001F, 0x000007E0, 0x0000F800}, si es que no lo escribía al
revés :(

Saludos

Miguel
Respuesta Responder a este mensaje
#4 Miguel
06/07/2004 - 22:14 | Informe spam
formato 565 (6 pixeles para el verde, por aquello de que el ojo humano


^^^^^^^^^
|-- 6 bits, claro...

Saludos

Miguel
Respuesta Responder a este mensaje
#5 Miguel
06/07/2004 - 22:30 | Informe spam
Tengo una duda adicional que no he podido solucionar a partir de lo
anterior: si la imagen fuera no de 8, sino de 24 bits por pixel, cómo debo
inicializar esta paleta de colores?.



Perdón otra vez, la respuesta era que no tienes una paleta, simplemente
le apuntas al BITMAPINFOHEADER, cuando la función vea el biBitCount $, no va a intentar leer más allá.

Saludos

Miguel
Respuesta Responder a este mensaje
Ads by Google
Help Hacer una preguntaSiguiente Respuesta Tengo una respuesta
Search Busqueda sugerida