Page 1 of 1

Crear BMP monocromo

Posted: Sun Dec 11, 2016 12:01 pm
by jmartial
Hola,

Necesito resolver un problema y no sé por donde meterle mano.

Tengo un bitmap en disco y necesito convertirlo en monocromo y volverlo a grabar en un fichero en el disco.

La idea es leer cada pixel y si es de cualquier color, ponerlo como negro y si es blanco, dejarlo blanco. Leer/Setear cada pixel es con getpixel()/setpixel(),
pero el resto de funciones necesarias no sé cual necesito.

Lo necesito para imprimirlo en una impresora monocromo y que su tamaño sea el más pequeño posible.

Re: Crear BMP monocromo

Posted: Mon Dec 12, 2016 11:31 am
by Antonio Linares
Joaquín,

La forma más rápida de hacerlo es usar la función de Windows BitBlt()

1. Creas un bitmap monocromo
HBITMAP hBmpMono = CreateBitmap( 100, 100, 1, 1, NULL );

2. Creas un hDC para usarlo con ese bitmap monocromo:
HDC hDcMono = CreateCompatibleDC( NULL );

3. Seleccionas ese bitmap monocromo en ese hDcMono y guardamos su "imagen" anterior:
HBITMAP hbmPrev = SelectBitmap( hDcMono, hBmpMono );

4. Lees el bitmap desde disco:
hBitmapColor = ReadBitmap( 0, cFileName )

5. Creas un hDC para usarlo con el bitmap de color:
HDC hDcColor = CreateCompatibleDC( NULL );

6. Copias el bitmap de color al bitmap monocromo:
BitBlt( hDcMono, 0, 0, 100, 100, hDcColor, 0, 0, SRCCOPY );

7. Salvas el bitmap monocromo a disco. Esté método de la Clase TWindow es lo que necesitas:

Code: Select all

METHOD SaveToBmp( cBmpFile ) CLASS TWindow

   local hBmp := WndBitmap( ::hWnd )
   local hDib := DibFromBitmap( hBmp )

   DibWrite( cBmpFile, hDib )
   GloBalFree( hDib )
   DeleteObject( hBmp )

return ( File( cBmpFile ) )

Re: Crear BMP monocromo

Posted: Mon Dec 12, 2016 12:17 pm
by jmartial
Muchas gracias Antonio.

Lo pruebo.

Re: Crear BMP monocromo

Posted: Mon Dec 12, 2016 9:35 pm
by Antonio Linares
Antes de llamar a BitBlt() tienes que seleccionar también el bitmap original en su hDC:

HBITMAP hbmPrev2 = SelectBitmap( hDcColor, hBitmapColor );

Re: Crear BMP monocromo

Posted: Tue Dec 13, 2016 9:18 am
by jmartial
Gracias Antonio,


Aunque ha funcionado, no es el efecto que esperaba, porque la imágen está un poco sucia, es decir, algunos puntos que deberían ser blancos no son exactamente blancos,
por lo que windows los pone negros.

Debido a esto, estoy investigando el poner en monocromo pero pudiendo aplicar un porcentaje de oscuridad ajustable.

Lo estoy probando con getpixel / setpixel, pero no sé si habrá otro sistema más rápido.

Re: Crear BMP monocromo

Posted: Tue Dec 13, 2016 10:22 am
by Antonio Linares
El sistema más rápido es BitBlt() pues está diseñado para mover bloques enteros de memoria de una vez

Revisa el código, por ejemplo, de la función DrawGrayed() en source\winapi\bmpdraw.c
y verás como usar BitBlt()