FiveTech Support Forums

FiveWin / Harbour / xBase community
Board index FiveWin para Harbour/xHarbour Leer pixeles de un bitmap monocromo
Posts: 458
Joined: Tue Mar 14, 2006 07:26 PM
Re: Leer pixeles de un bitmap monocromo
Posted: Fri Jul 24, 2015 09:19 AM
Respondo por partes:

Este es código Antonio:

Code (fw): Select all Collapse
    hBitmap es el handle después de cargar el bmp desde disco 

    hDC        := CreateDC("DISPLAY",NIL,NIL,NIL)
    hDCMem     := CreateCompatibleDC( 0 ) //hDC )
    hDCMemDest := CreateCompatibleDC( 0 )
    hOldBmp    := SelectObject( hDCMem, hBitmap ) 

   newHeight := 100 // Nueva altura por ejemplo

   BitBlt( hDCMem, 0, 0, :nWidth, newHeight, hDCMemDest, 0, 0, SRCCOPY )

   // Ahora necesito guardar hDCMem como un nuevo bitmap en disco
   //--------- Con FreeLibrary ---------
      nFormat := FI_GETFILETYPE( cFile, 0 )
      hDib       := FI_LOAD( nFormat, cFile, 0 )
      hInfoH    := FI_GETINFOHEADER( hDib )
      hInfo      := FI_GETINFO( hDib )
      hBits      := FI_GETBITS( hDib )

     hBmp = CreateDiBitmap( hDCMemDest, hInfoH, CBM_INIT, hBits, hInfo, DIB_RGB_COLORS )
  
     // hBmp devuelve 0, no lo crea

    Y aquí me he quedado...



Manuel, lo que pretendo es teniendo un bitmap monocromo en disco con altura 1000 pixeles, copiarlo a disco recortándolo a 300 pixeles de altura.
Me gustaría hacerlo sin GDI+, tengo FWH de final de 2014 y me gustaría que fuera lo más fácil posible.

También podría hacerlo con freeImage, pero no he encontrado la forma.

Gracias,
Joaquín Martínez
Un Saludo,

Joaquín Martínez
Posts: 44158
Joined: Thu Oct 06, 2005 05:47 PM
Re: Leer pixeles de un bitmap monocromo
Posted: Fri Jul 24, 2015 09:45 AM

Joaquín,

Prueba asi, teniendo seleccionado el bitmap original en hDC:

HDC hDCMem = CreateCompatibleDC( hDC );
HBITMAP hBmp = CreateCompatibleBitmap( hDC, rc->right - rc->left, rc->bottom -
rc->top );
HBITMAP hBmpOld = ( HBITMAP ) SelectObject( hDCMem, hBmp );
BitBlt( hDCMem, 0, 0, rc->right, rc->bottom, hDC, 0, 0, SRCCOPY );
SelectObject( hDCMem, hBmpOld );
DeleteDC( hDCMem );

regards, saludos

Antonio Linares
www.fivetechsoft.com
Posts: 44158
Joined: Thu Oct 06, 2005 05:47 PM
Re: Leer pixeles de un bitmap monocromo
Posted: Fri Jul 24, 2015 09:47 AM

Para un bitmap monocromo sería asi:

hBmpMono = CreateBitmap( rc->right - rc->left, rc->bottom - rc->top, 1, 1, NULL );

regards, saludos

Antonio Linares
www.fivetechsoft.com
Posts: 44158
Joined: Thu Oct 06, 2005 05:47 PM
Re: Leer pixeles de un bitmap monocromo
Posted: Fri Jul 24, 2015 09:55 AM
Prueba asi:

Se le podria pasar la cantidad a disminuir la altura como un segundo parámetro

Code (fw): Select all Collapse
HB_FUNC( BMPCOPY ) // hBitmap --> hNewBitmap
{
   HBITMAP hBmpMem, hOldBmp, hOldBmp2;
   HDC hDC     = CreateDC("DISPLAY", 0, 0, 0);
   HDC hDCMem  = CreateCompatibleDC( hDC );
   HDC hDCMem2 = CreateCompatibleDC( hDC );
   HBITMAP hBitmap = (HBITMAP) hb_parnl( 1 );
   BITMAP bm;

   GetObject( ( HGDIOBJ ) hBitmap, sizeof( BITMAP ), ( LPSTR ) &bm );

   bm.bmHeight -= cantidad que quieras disminuir la altura;

   hBmpMem = CreateBitmap( bm.bmWidth, bm.bmHeight, 1, 1, NULL );
   hOldBmp = (HBITMAP) SelectObject( hDCMem, hBmpMem );
   hOldBmp2 = (HBITMAP) SelectObject( hDCMem2, hBitmap );

   BitBlt( hDCMem, 0, 0, bm.bmWidth, bm.bmHeight, hDCMem2, 0, 0, SRCCOPY );

   SelectObject( hDCMem, hOldBmp );
   SelectObject( hDCMem2, hOldBmp2 );
   DeleteDC( hDCMem );
   DeleteDC( hDCMem2 );
   DeleteDC( hDC );

   hb_retnl( (LONG) hBmpMem );
}
regards, saludos

Antonio Linares
www.fivetechsoft.com
Posts: 458
Joined: Tue Mar 14, 2006 07:26 PM
Re: Leer pixeles de un bitmap monocromo
Posted: Fri Jul 24, 2015 09:58 AM

Antonio,

¿para un bitmap monocromo, como indico el HDC original ?

Con CreateCompatibleBitmap sí tiene ese parámetro.

Un Saludo,

Joaquín Martínez
Posts: 458
Joined: Tue Mar 14, 2006 07:26 PM
Re: Leer pixeles de un bitmap monocromo
Posted: Fri Jul 24, 2015 10:09 AM
Antonio,

Muchas gracias, lo corta, pero no se graba bien, se graba totalmente negro. Esto ya me pasó en otras pruebas que hice.

Este es el código que pongo:

Code (fw): Select all Collapse
   hNewBitmap := bmpCopy( hBmp, newHeight )  // Le he puesto la altura como parámetro
   
   hDib := DibFromBitmap( hNewBitmap )
   dibWrite( "impresoCortado.bmp", hDib )


¿ Que me falta ?
Un Saludo,

Joaquín Martínez
Posts: 44158
Joined: Thu Oct 06, 2005 05:47 PM
Re: Leer pixeles de un bitmap monocromo
Posted: Fri Jul 24, 2015 10:39 AM

Antes del BitBlt() prueba a hacer:

SetBkColor( hDCMem, GetPixel( hBitmap, 0, 0 ) );

regards, saludos

Antonio Linares
www.fivetechsoft.com
Posts: 458
Joined: Tue Mar 14, 2006 07:26 PM
Re: Leer pixeles de un bitmap monocromo
Posted: Fri Jul 24, 2015 11:32 AM

Antonio,

No ha arreglado nada. Sigue saliendo en negro el bitmap resultante.

No se me ocurre más nada.

Un Saludo,

Joaquín Martínez
Posts: 458
Joined: Tue Mar 14, 2006 07:26 PM
Re: Leer pixeles de un bitmap monocromo
Posted: Fri Jul 24, 2015 12:37 PM

Antonio,

Gracias, ya funciona.

Tu función bmpCopy() funciona perfecta.

Me salía negro, porque antes había buscado por donde había que cortar seleccionando un hDC y antes de llamar a tu función tenía que restaurarlo poniendo
SelectObject( hDCMem, hOldBmp ).

Pero bueno, que tu función corta perfectamente un bitmap.

Muchas gracias,
Joaquín Martínez

Un Saludo,

Joaquín Martínez
Posts: 44158
Joined: Thu Oct 06, 2005 05:47 PM
Re: Leer pixeles de un bitmap monocromo
Posted: Sat Jul 25, 2015 08:33 AM

Muy bien! :-)

regards, saludos

Antonio Linares
www.fivetechsoft.com
Posts: 498
Joined: Thu May 10, 2007 08:30 PM
Re: Leer pixeles de un bitmap monocromo
Posted: Sun Jul 26, 2015 06:04 PM

A lo mejor te parece una tontería, pero el fichero, si es un BMP monocromo, se compondrá de una cabecera BITMAPINFOHEADER seguido de los BYTES (8 bits) de la imagen. Un byte 0 es negro y un byte 1 es blanco. Si averiguas cuanto mide la cabecera (medida fija), puedes abrir el fichero con un MEMOWRIT y leer los bytes 0 y 1 con un Substr() empezando por el que sigue a la cabecera. Yo hice hace tiempo algo parecido con un bitmap de 24 bits y me funcionó. Lo que pasa que no recuerdo cuanto mide esa cabecera.

Otra cosa. Las líneas del bitmap han de medir todas una cantidad múltiplo de cuatro. Es decir si el BMP mide 398 pixels de ancho, cada línea del BMP tendrá 400 pixels en ese fichero, los dos últimos bytes serán ceros. Y, por ultimo, a quien diseño los ficheros y su manipulación, se le ocurrió la feliz idea de guardar las línea del BMP en orden inverso. Es decir la primera línea de 400 pixels del supuesto BMP del ejemplo representa a la última línea que se dibuja en pantalla. La segunda es la penúltima, la tercera la antepenúltima, etc. Están en orden inverso las líneas, no los bytes que las forman. Como si coges la primera línea, tal cual, y la pones al final. Después coges la nueva primera línea y la pones delante de la última (la penúltima), etc... no se si me explico.

Nunca he trabajado con BMP´s monocromos, así que a lo mejor, en lugar de BYTES, la imagen se guarda como BITS. Pero seguramente cada línea tendrá que medir múltiplo de 4 y las líneas irán en orden inverso.

Es cuestión de que investigues un poco en internet et voilà.

Un saludo

Peaaaaaso de foro...

FWH 2007 - xHarbour - BCC55
Posts: 498
Joined: Thu May 10, 2007 08:30 PM
Re: Leer pixeles de un bitmap monocromo
Posted: Sun Jul 26, 2015 06:24 PM

A lo mejor te parece una tontería, pero: tu fichero, si es un BMP monocromo se compondrá de una cabecera BITMAPINFOHEADER seguido de los BYTES (8 BITS) de la imagen. Por la tanto, si averiguas cuánto mide esa cabecera podrás abrir el fichero con MEMOWRIT y leer los bytes de la imagen con Substr(). Un byte a 0 significa color negro y un byte 1 color blanco (creo). Yo lo hice hace algunos años con un bitmap de 24 bits y me fue muy bien.

Sólo tienes que tener en cuenta dos cosas.

1 .- Cada línea del bitmap tiene que medir una cantidad de bytes múltiplo de 4. Por ejemplo si la imagen mide 398 pixels de ancho, cada línea ocupará 400 bytes en el fichero. Los dos últimos bytes serán ceros.

2 .- A quien diseño los ficheros BMP se le ocurrió la feliz idea de guardar las líneas en orden inverso. Las líneas, no los bytes que las componen. Significa que tras la cabecera estará la información de la última línea de la imagen, seguida de la información de la penúltima, la antepenúltima, etc. Por lo tanto,el primer byte tras la cabecera representa el color del primer pixel de la última línea de la imagen. Seguido del segundo pixel de la última línea, y así hasta el final. El último byte del fichero será el último byte de la primera línea de la imagen, o uno, dos o tres ceros de relleno para que la línea mida una cantidad múltiplo de 4. Por lo tanto en esa imagen de 398 pixels de ancho, los dos últimos bytes serán 00 y el antepenúltimo será el color del último byte de la primera línea de la imagen. El primer byte de la primera línea estará en la posición: longitud del fichero menos 400.

Nunca he trabajado con BMP's monocromos. Por lo tanto puede ocurrir que en lugar de guardar la imagen en BYTES lo haga en BITS. Pero seguramente cada línea medirá una cantidad múltiplo de 4 y las líneas se habrán guardado en orden inverso.

Un saludo

Peaaaaaso de foro...

FWH 2007 - xHarbour - BCC55
Posts: 498
Joined: Thu May 10, 2007 08:30 PM
Re: Leer pixeles de un bitmap monocromo
Posted: Sun Jul 26, 2015 06:35 PM

Perdona jmarcial. No había visto que había una segunda página de posts y pensé que no había mandado el mensaje, por eso está duplicado.

Aquí te lo explican de forma muy sencilla:

http://es.ccm.net/contents/719-el-forma ... te-fichier
Y sí se guarda como BITS y no como BYTES.

Un saludo

Peaaaaaso de foro...

FWH 2007 - xHarbour - BCC55
Posts: 498
Joined: Thu May 10, 2007 08:30 PM
Re: Leer pixeles de un bitmap monocromo
Posted: Sun Jul 26, 2015 06:47 PM

He estado mirando por encima y resulta que el BITMAPINFOHEADER mide 40 bytes, pero los ficheros, además de eso tienen, delante, tienen un BITMAPFILEHEADER que mide 14 bytes. Luego, la información de la imagen debería empezar en el 55º byte. Suponiendo que utilice paleta. Claro que un bitmap monocromo, no creo que utilice paleta, ni tabla de colores.... Pero, y si sí...

Peaaaaaso de foro...

FWH 2007 - xHarbour - BCC55
Posts: 458
Joined: Tue Mar 14, 2006 07:26 PM
Re: Leer pixeles de un bitmap monocromo
Posted: Mon Jul 27, 2015 07:27 AM

Gracias Antolin,

Pero haciéndolo con las funciones del API de windows para cargar el bitmap y buscando el color con getPixel(), creo que es más limpio, seguro y rápido.

Lo que planteas está bien pero, vamos un poco a ciegas, contando que luego para cortarlo exactamente en un número de pixeles, creo que es más problemático, además de que hay que calcular mucho innecesariamente, ya que como te digo, usando el API no te tienes que preocupar de todo eso.

Un Saludo,

Joaquín Martínez