Pintar un pixel sobre un Bmp
- Rafael Clemente
- Posts: 365
- Joined: Sat Oct 08, 2005 7:59 pm
- Location: Barcelona, Spain
Pintar un pixel sobre un Bmp
Supongamos que tengo un Bmp de -por ejemplo- 3000 x 1200 pixels, o sea, que no cabe entero en pantalla sin redimensionarlo.
Mi pregunta es: Alguien podría darme una receta o función para pintar UN pixel directamente sobre el archivo BMP (NO sobre pantalla) de un color determinado. Algo así: FnPintar(".\MiBmp.bmp", 500, 400, CLR_GREEN)
Muchísimas gracias
Rafael
Mi pregunta es: Alguien podría darme una receta o función para pintar UN pixel directamente sobre el archivo BMP (NO sobre pantalla) de un color determinado. Algo así: FnPintar(".\MiBmp.bmp", 500, 400, CLR_GREEN)
Muchísimas gracias
Rafael
- Antonio Linares
- Site Admin
- Posts: 37481
- Joined: Thu Oct 06, 2005 5:47 pm
- Location: Spain
- Contact:
Rafael,
Para modificar el pixel tienes que cargarlo en un hDC, que no quiere decir que tengas que visualizarlo:
local hOld := SelectObject( oWnd:hDC, hBitmap )
SetPixel( oWnd:hDC, ... )
Guardar el bitmap a disco nuevamente
SelectObject( oWnd:hDC, hOld )
Si explicas un poco más lo que quieres hacer, podemos ver la forma idónea de guardarlo
Para modificar el pixel tienes que cargarlo en un hDC, que no quiere decir que tengas que visualizarlo:
local hOld := SelectObject( oWnd:hDC, hBitmap )
SetPixel( oWnd:hDC, ... )
Guardar el bitmap a disco nuevamente
SelectObject( oWnd:hDC, hOld )
Si explicas un poco más lo que quieres hacer, podemos ver la forma idónea de guardarlo
- Rafael Clemente
- Posts: 365
- Joined: Sat Oct 08, 2005 7:59 pm
- Location: Barcelona, Spain
Antonio: Gracias por tu sugerencia. Valos a ver si podemos adelantar algo más:
Se trata de diseñar un sistema que permita pintar sobre un plano el trayecto recorrido por un automóvil equipado con un receptor GPS. Ya tengo el sistema que captura las coordenadas del GPS, segundo a segundo. Está hecho con FWPPC y va de maravilla. Ahora se trata de ponerlo en gráfico.
Lo lógico sería utilizar un plano dibujado en AutoCad, o sea, en formato vectorial. El problema es que de ese formato no tengo ni idea, así que pensé que quizás sería más fácil hacerlo con un plano escaneado en forma de bitmap y me pareció que el BMP era el formato más simple. A lo mejor estoy equivocado y alguien sabe cómo hacerlo en vectorial o incluso en formatos más comprimidos como el Jpg.
Para tener una resolución adecuada, el BMP ha de ser muy grande (tengo uno de muestra que tiene casi 100 Mb), así que no es posible presentarlo adecuadamente en pantalla. De ahí mi requisito de marcar pixels directamente sobre el archivo.
¿Qué pixels hay que marcar? Se tratará de interpolar las coordenadas GPS, punto a punto sobre el propio plano tomando como referencia sus vértices, cuyas coordenadas son conocidas. Puede ser un trabajo laborioso pero no parece muy complicado.
En fin, incluso puede ser que exista ya alguna librería que facilite el trabajo aunque preferiría utilizar código propio. Me podrías dar alguna idea o -mejor aún- un esqueleto de programa por donde empezar? Por ejemplo, en tu sugerencia, qué es hBitmap? Si no he visualizado la imagen, cómo obtengo su handle? Y oWnd:hDc, a qué ventana se refiere? Perdona por las preguntas de principiante pero es que esto de SelectObject() y los hDc siempre me ha resultado un poco misterioso.
Gracias y un saludo,
Rafael
Se trata de diseñar un sistema que permita pintar sobre un plano el trayecto recorrido por un automóvil equipado con un receptor GPS. Ya tengo el sistema que captura las coordenadas del GPS, segundo a segundo. Está hecho con FWPPC y va de maravilla. Ahora se trata de ponerlo en gráfico.
Lo lógico sería utilizar un plano dibujado en AutoCad, o sea, en formato vectorial. El problema es que de ese formato no tengo ni idea, así que pensé que quizás sería más fácil hacerlo con un plano escaneado en forma de bitmap y me pareció que el BMP era el formato más simple. A lo mejor estoy equivocado y alguien sabe cómo hacerlo en vectorial o incluso en formatos más comprimidos como el Jpg.
Para tener una resolución adecuada, el BMP ha de ser muy grande (tengo uno de muestra que tiene casi 100 Mb), así que no es posible presentarlo adecuadamente en pantalla. De ahí mi requisito de marcar pixels directamente sobre el archivo.
¿Qué pixels hay que marcar? Se tratará de interpolar las coordenadas GPS, punto a punto sobre el propio plano tomando como referencia sus vértices, cuyas coordenadas son conocidas. Puede ser un trabajo laborioso pero no parece muy complicado.
En fin, incluso puede ser que exista ya alguna librería que facilite el trabajo aunque preferiría utilizar código propio. Me podrías dar alguna idea o -mejor aún- un esqueleto de programa por donde empezar? Por ejemplo, en tu sugerencia, qué es hBitmap? Si no he visualizado la imagen, cómo obtengo su handle? Y oWnd:hDc, a qué ventana se refiere? Perdona por las preguntas de principiante pero es que esto de SelectObject() y los hDc siempre me ha resultado un poco misterioso.
Gracias y un saludo,
Rafael
- Rafael Clemente
- Posts: 365
- Joined: Sat Oct 08, 2005 7:59 pm
- Location: Barcelona, Spain
Antonio:
Más o menos, ya estoy en camino de resolverlo. Es cuestión a abrir el Bmp con FOPEN(), analizar el header del Bmp (no es complicado), calcular la posición del pixel que quiero pintar (ojo, que en cada línea pueden haber hasta tres bytes 00 de relleno) y hacer un FWRITE() del color apropiado en ese pixel. Laborioso pero después de unas cuantas pruebas, la cosa parece clara.
Por cierto, si alguien quiere intentarlo, le recomiendo que utilice como foto de partida un Bmp en blanco. Así, toda la zona de datos son bytes FF y es mucho más fácil de analizar _
Saludos,
Rafael
Más o menos, ya estoy en camino de resolverlo. Es cuestión a abrir el Bmp con FOPEN(), analizar el header del Bmp (no es complicado), calcular la posición del pixel que quiero pintar (ojo, que en cada línea pueden haber hasta tres bytes 00 de relleno) y hacer un FWRITE() del color apropiado en ese pixel. Laborioso pero después de unas cuantas pruebas, la cosa parece clara.
Por cierto, si alguien quiere intentarlo, le recomiendo que utilice como foto de partida un Bmp en blanco. Así, toda la zona de datos son bytes FF y es mucho más fácil de analizar _
Saludos,
Rafael
- Paco Garcia
- Posts: 172
- Joined: Fri Oct 07, 2005 12:00 pm
- Contact:
Hola Rafael
Para pintar en un bitmap como bien dice Antonio debes hacer esto:
Si necesitas algo mas, pues cuenta
Podrias tambien investigar los Metafiles. Eso sería dibujo vectorial y ocupan poco. Un metafile es básicamente hacer el CreateMetafile y las funciones de dibujo de toda la vida. Luego estas llamadas a funciones se quedan almacenadas dentro del metafile como si de un dbf se tratase lo único que ocupa menos que un bitmap.
Paco
Para pintar en un bitmap como bien dice Antonio debes hacer esto:
Code: Select all
local hBmp := ReadBitmap( 0, cBitmap )
local hDC := CreateDC( "DISPLAY",0,0,0)
local hDCMem := CreateCompatibleDC( hDC )
local hOldBmp := SelectObject( hDCMem, hBmp )
local nWBmp := nBmpWidth( hBmp )
local nHBmp := nBmpHeight( hBmp )
DeleteDC( hDC )
// ya tienes todo lo necesario
// ahora pintar
Moveto( hDCmem, 10, 10 )
Lineto( hDCMem, 100, 100 )
SelectObject( hDCMem, hOldBmp )
DeleteDC( hDCMem )
// si quieres guardar el bmp otra vez pues pasalo a Dib y luego a disco
Return hbmp // o lo que quieras
Podrias tambien investigar los Metafiles. Eso sería dibujo vectorial y ocupan poco. Un metafile es básicamente hacer el CreateMetafile y las funciones de dibujo de toda la vida. Luego estas llamadas a funciones se quedan almacenadas dentro del metafile como si de un dbf se tratase lo único que ocupa menos que un bitmap.
Paco
- Rafael Clemente
- Posts: 365
- Joined: Sat Oct 08, 2005 7:59 pm
- Location: Barcelona, Spain
Paco:
Aunque con un poco de retraso he probado tu sugerencia pero me da un error de
¿Por favor, me puedes decir qué me falta?
Rafael
Aunque con un poco de retraso he probado tu sugerencia pero me da un error de
Code: Select all
Error: Unresolved external '_HB_FUN_CREATECOMPATIBLEDC'
Rafael
- Antonio Linares
- Site Admin
- Posts: 37481
- Joined: Thu Oct 06, 2005 5:47 pm
- Location: Spain
- Contact:
Rafael,
Code: Select all
HB_FUNC( CREATECOMPATIBLEDC )
{
hb_retnl( ( LONG ) CreateCompatibleDC( ( HDC ) hb_parnl( 1 ) ) );
}
- Rafael Clemente
- Posts: 365
- Joined: Sat Oct 08, 2005 7:59 pm
- Location: Barcelona, Spain
Antonio: Gracias. Ya compila. Ahora ¿Cómo puedo crear el Bmp modificato?. Algo así:
Rafael
Code: Select all
...
hBmp := ReadBitmap( 0, cBitmap )
hDC := CreateDC( "DISPLAY",0,0,0)
hDCMem := CreateCompatibleDC( hDC )
hOldBmp := SelectObject( hDCMem, hBmp )
nWBmp := nBmpWidth( hBmp )
nHBmp := nBmpHeight( hBmp )
DeleteDC( hDC )
MoveTo(hDCmem, 10, 10 )
Lineto( hDCMem, 100, 100 ) // Hasta aquí, parece que va bien
DibWrite(".\prueba.bmp", hDcMem) // <---- Aquí me da un GPF ¿cómo lo hago?
SelectObject( hDCMem, hOldBmp )
DeleteDC( hDCMem )
...
- Paco Garcia
- Posts: 172
- Joined: Fri Oct 07, 2005 12:00 pm
- Contact:
- Rafael Clemente
- Posts: 365
- Joined: Sat Oct 08, 2005 7:59 pm
- Location: Barcelona, Spain
Paco:
Muchas gracias. Para imágenes pequeñas (30 K) tu programa funciona perfecto; para las grandes (lo he probado con un bmp de 9 M) da un error en DibWrite() pero supongo que eso es normal tratándose de archivos tan grandes.
Entretanto, yo he estado experimentando en pintar directamente pixels sobre el archivo Bmp y por ahora funciona bastante bien. Claro que es mucho más engorroso pero para salir del paso ya me sirve
Gracias otra vez y un saludo,
Rafael
Muchas gracias. Para imágenes pequeñas (30 K) tu programa funciona perfecto; para las grandes (lo he probado con un bmp de 9 M) da un error en DibWrite() pero supongo que eso es normal tratándose de archivos tan grandes.
Entretanto, yo he estado experimentando en pintar directamente pixels sobre el archivo Bmp y por ahora funciona bastante bien. Claro que es mucho más engorroso pero para salir del paso ya me sirve
Gracias otra vez y un saludo,
Rafael
Los ficheros de AutoCad son "texto", añadir mas texto (o insertar) no seria complicado. Digo yo.Rafael Clemente wrote:...Lo lógico sería utilizar un plano dibujado en AutoCad, o sea, en formato vectorial...
Mi abuelo decía: Los aviones vuelan porque Dios quiere, y los helicópteros ni Dios sabe porque vuelan.
FWH 16.02, xHarbour 1.2.3, Harbour 3.2.0, WorkShop 4.5, AJ Make 0.30, Borlan BCC 7.00, VisualStudio 2013
FWH 16.02, xHarbour 1.2.3, Harbour 3.2.0, WorkShop 4.5, AJ Make 0.30, Borlan BCC 7.00, VisualStudio 2013