Cómo dibujar un rectángulo de tamaño ajustable
- Rafael Clemente
- Posts: 365
- Joined: Sat Oct 08, 2005 7:59 pm
- Location: Barcelona, Spain
Cómo dibujar un rectángulo de tamaño ajustable
Alguien podría darme un ejemplo de cómo dibujar un rectángulo de tamaño variable, o sea, el tipo de rectángulos utilizados para seleccionar una porción de un bitmap, que se expanden o se contraen al mover el ratón manteniendo pulsado el botón izquierdo.
Gracias,
Rafael
Gracias,
Rafael
- Antonio Linares
- Site Admin
- Posts: 37481
- Joined: Thu Oct 06, 2005 5:47 pm
- Location: Spain
- Contact:
- Rafael Clemente
- Posts: 365
- Joined: Sat Oct 08, 2005 7:59 pm
- Location: Barcelona, Spain
- Rafael Clemente
- Posts: 365
- Joined: Sat Oct 08, 2005 7:59 pm
- Location: Barcelona, Spain
- reinaldocrespo
- Posts: 918
- Joined: Thu Nov 17, 2005 5:49 pm
- Location: Fort Lauderdale, FL
Rafael;
Hola, que tal?
Cual es tu proposito?
Si se trata de enmarcar un segmento de una imagen (timage), pues me gustaría poder usarlo.
Es que tengo una rutina que adquire documentos o imagenes de un scanner, y me gustaria permitir al usuario marcar el area de la imagen que desea conservar.
Saludos,
Reinaldo.
Hola, que tal?
Cual es tu proposito?
Si se trata de enmarcar un segmento de una imagen (timage), pues me gustaría poder usarlo.
Es que tengo una rutina que adquire documentos o imagenes de un scanner, y me gustaria permitir al usuario marcar el area de la imagen que desea conservar.
Saludos,
Reinaldo.
- Rafael Clemente
- Posts: 365
- Joined: Sat Oct 08, 2005 7:59 pm
- Location: Barcelona, Spain
Reinaldo:
Aproximadamente es eso: Se trata de marcar una zona de interés dentro de un diálogo (podría ser un Bmp pero es un diálogo; no creo que eso importe). Una vez marcado el rectángulo, me guardaré las coordenadas de inicio y fin para procesar el contenido de esa zona. Igual que harías tú al marcar una región de la foto escaneada para recortarla y crear de ella una imagen independiente.
Lo que pasa es que me he liado de mala manera con lo de pintar el rectángulo (eso es fácil) y borrarlo al desplazar el ratón hasta el siguiente pixel para poder volverlo a pintar. Esa es la rutina que más o menos estoy buscando.
De todas formas, aún me tengo que estudiar el ejemplo que ha propuesto Antonio. Un saludo.
Rafael
Aproximadamente es eso: Se trata de marcar una zona de interés dentro de un diálogo (podría ser un Bmp pero es un diálogo; no creo que eso importe). Una vez marcado el rectángulo, me guardaré las coordenadas de inicio y fin para procesar el contenido de esa zona. Igual que harías tú al marcar una región de la foto escaneada para recortarla y crear de ella una imagen independiente.
Lo que pasa es que me he liado de mala manera con lo de pintar el rectángulo (eso es fácil) y borrarlo al desplazar el ratón hasta el siguiente pixel para poder volverlo a pintar. Esa es la rutina que más o menos estoy buscando.
De todas formas, aún me tengo que estudiar el ejemplo que ha propuesto Antonio. Un saludo.
Rafael
- reinaldocrespo
- Posts: 918
- Joined: Thu Nov 17, 2005 5:49 pm
- Location: Fort Lauderdale, FL
Rafael;
Pues usando los ejemplos que Antonio menciona le añadí estos metodos a la clase timage y me dibuja el rectangulo sobre la imagen. Hasta ahi, no hay problema. Donde tengo el problema es descifrando que hacer con las coordenadas de forma tal que la imagen ahora solo venga a ser esa region enmarcada.
No se si esto te ayuda.
Reinaldo.
Pues usando los ejemplos que Antonio menciona le añadí estos metodos a la clase timage y me dibuja el rectangulo sobre la imagen. Hasta ahi, no hay problema. Donde tengo el problema es descifrando que hacer con las coordenadas de forma tal que la imagen ahora solo venga a ser esa region enmarcada.
Code: Select all
//----------------------------------------------------------------------------//
METHOD LButtonDown( nRow, nCol, nFlags ) CLASS TImage
if ::bLClicked != nil
Eval( ::bLClicked, nRow, nCol, nFlags )
else
::lBoxDraw = .t.
::nBoxTop = nRow
::nBoxLeft = nCol
::nBoxBottom = nRow
::nBoxRight = nCol
::Capture()
::DrawBox()
endif
return nil
//----------------------------------------------------------------------------//
METHOD MouseMove( nRow, nCol, nFlags ) CLASS TImage
if ::lBoxDraw
::DrawBox()
::nBoxBottom = nRow
::nBoxRight = nCol
::DrawBox()
endif
return Super:MouseMove( nRow, nCol, nFlags )
//----------------------------------------------------------------------------//
METHOD LButtonUp( nRow, nCol, nFlags ) CLASS TImage
if ::lBoxDraw
::DrawBox()
::lBoxDraw = .f.
ReleaseCapture()
// ::nWidth := ::nBoxRight - ::nBoxLeft
// ::nHeight := ::nBoxBottom - ::nBoxTop
Super:ScrollAdjust()
Super:refresh( .t. )
endif
return nil
Reinaldo.
- Rafael Clemente
- Posts: 365
- Joined: Sat Oct 08, 2005 7:59 pm
- Location: Barcelona, Spain
- Paco Garcia
- Posts: 172
- Joined: Fri Oct 07, 2005 12:00 pm
- Contact:
DrawFocusRect
Hola
Puedes utilizar tambien DrawFocusRect. Esta función es la típica para marcar un rectángulo punteado
La primera vez que pintas, dibuja. La segunda vez que pintas en un mismo sitio te borra lo anterior. Con un poco de habilidad puedes lograr el efecto deseado.
Puedes utilizar tambien DrawFocusRect. Esta función es la típica para marcar un rectángulo punteado
La primera vez que pintas, dibuja. La segunda vez que pintas en un mismo sitio te borra lo anterior. Con un poco de habilidad puedes lograr el efecto deseado.
Code: Select all
#pragma BEGINDUM
HB_FUNC( DRAWFOCUSRECT )
{
RECT rc;
rc.top = hb_parni( 2, 1 );
rc.left = hb_parni( 2, 2 );
rc.bottom = hb_parni( 2, 3 );
rc.right = hb_parni( 2, 4 );
hb_retl( DrawFocusRect( (HDC) hb_parnl( 1 ), &rc ) );
}
#pragma ENDDUMP
- Rafael Clemente
- Posts: 365
- Joined: Sat Oct 08, 2005 7:59 pm
- Location: Barcelona, Spain
Paco: Problema resuelto
Paco:
Gracias por tu idea de utilizar DrawFocusRect(). Ya me funciona, simplemente utilizando bMMoved() y bLClicked(). El truco -si a alguien le sirve de algo- está en llamar dos veces a DrawFocusRect(): La primera para borrar el rectángulo anterior, la segunda para dibujar uno nuevo en unas coordenadas ligeramente distintas.
Un saludo,
Rafael
Gracias por tu idea de utilizar DrawFocusRect(). Ya me funciona, simplemente utilizando bMMoved() y bLClicked(). El truco -si a alguien le sirve de algo- está en llamar dos veces a DrawFocusRect(): La primera para borrar el rectángulo anterior, la segunda para dibujar uno nuevo en unas coordenadas ligeramente distintas.
Un saludo,
Rafael
- Rafael Clemente
- Posts: 365
- Joined: Sat Oct 08, 2005 7:59 pm
- Location: Barcelona, Spain
Reinaldo:
Como ver en mi post anterior, ya tengo mi problema resuelto.
Respecto a tu pregunta, se me ocurren dos formas de obtener una subimagen de TImage():
1.- Leyendo pixel a pixel el trozo que has seleccionado (con GetPixel()) y montandote tú la imagen. El problema es construir las cabeceras y cola del archivo. Total: Tan complicado, que no vale la pena ni intentarlo.
2.- Utiliza nConvert. Lo encuentras aquí: http://perso.wanadoo.fr/pierre.g/xnview ... nvert.html. En un programa excelente y gratuito para uso privado. Incluso si has de comprar una licencia -como yo hice- vale la pena.
Una vez tienes las coordenadas de tu rectángulo (x1,y1,x2,x2), simplemente haz:
y ya está.
Yo te he puesto el ejemplo en formato Bmp, pero puedes trabajar en cualquier otro.
Un saludo,
Rafael
Como ver en mi post anterior, ya tengo mi problema resuelto.
Respecto a tu pregunta, se me ocurren dos formas de obtener una subimagen de TImage():
1.- Leyendo pixel a pixel el trozo que has seleccionado (con GetPixel()) y montandote tú la imagen. El problema es construir las cabeceras y cola del archivo. Total: Tan complicado, que no vale la pena ni intentarlo.
2.- Utiliza nConvert. Lo encuentras aquí: http://perso.wanadoo.fr/pierre.g/xnview ... nvert.html. En un programa excelente y gratuito para uso privado. Incluso si has de comprar una licencia -como yo hice- vale la pena.
Una vez tienes las coordenadas de tu rectángulo (x1,y1,x2,x2), simplemente haz:
Code: Select all
WaitRun('nconvert -out bmp -crop ' + STR(x1) + STR(y1) + STR(x2-x1+1) + STR(y2-y1+1) + '-quiet -o Recorte.bmp "FotoOrig.bmp"', 0)
Yo te he puesto el ejemplo en formato Bmp, pero puedes trabajar en cualquier otro.
Un saludo,
Rafael
- Paco Garcia
- Posts: 172
- Joined: Fri Oct 07, 2005 12:00 pm
- Contact:
Hola Rafael.
Cualquier método es bueno si consigues tu meta pero es un poco matar _ a cañonazos.
A ver que te parece esto:
Un saludo
Cualquier método es bueno si consigues tu meta pero es un poco matar _ a cañonazos.
A ver que te parece esto:
Code: Select all
function CopiaRect( oWnd, aRect )
local hBmp := WndCopy4( oWnd:hWnd, aRect )
DibWrite( "screen.bmp", DibFromBitmap( hBmp ) )
DeleteObject( hBmp )
return nil
#pragma BEGINDUMP
#include "windows.h"
#include "hbapi.h"
HB_FUNC( WNDCOPY4 )
{
HWND hWnd = ( HWND ) hb_parnl( 1 );
HDC hDC = GetWindowDC( hWnd );
int x = hb_parni( 2, 2 )+1;
int y = hb_parni( 2, 1 )+1;
int cx = hb_parni( 2, 4 ) - x-2;
int cy = hb_parni( 2, 3 ) - y-2;
HDC hMemDC;
HBITMAP hBitmap, hOldBmp;
hMemDC = CreateCompatibleDC( hDC );
hBitmap = CreateCompatibleBitmap( hDC, cx, cy );
hOldBmp = ( HBITMAP ) SelectObject( hMemDC, hBitmap );
StretchBlt(hMemDC, 0, 0, cx, cy, hDC, x, y,cx, cy, SRCCOPY );
SelectObject( hMemDC, hOldBmp );
DeleteDC( hMemDC );
ReleaseDC( hWnd, hDC );
hb_retnl( (LONG ) hBitmap );
}
#pragma ENDDUMP
- Rafael Clemente
- Posts: 365
- Joined: Sat Oct 08, 2005 7:59 pm
- Location: Barcelona, Spain
- Paco Garcia
- Posts: 172
- Joined: Fri Oct 07, 2005 12:00 pm
- Contact:
Pues si mire "uste"
Resulta que Antonio Linares se ha decidido a dar el paso de "adoptar" Freeimage para mostrar imágenes. La forma de convertir a otro formato es:
Pues mas o menos es esto. Parte la he sacado de una contribución que hizo Rafa Carmona. (Saludos Rafacarmona)
Un saludo
http://www.google.es/search?hl=es&q=freeimage&meta=
Resulta que Antonio Linares se ha decidido a dar el paso de "adoptar" Freeimage para mostrar imágenes. La forma de convertir a otro formato es:
Code: Select all
Function SaveImage( cFile, nFormat, nFlag )
local lOk
local hDib
// 0 -> Bmp
// 2 -> Jpg
// 13 -> Png
DEFAULT nFormat := fiGetFileType( cFile, 0 )
hDib := fiLoad( nFormat, cFile, 0 )
if hDib == 0
MsgStop( "No image loaded" )
return nil
endif
lOk := fiSave( nFormat, hDib, cFile, nFlag )
if !lOk
MsgInfo( "Can't not save file" )
endif
return Nil
DLL32 STATIC FUNCTION FILOAD( nFormat AS LONG, cFileName AS LPSTR,nFlags AS LONG ) AS LONG;
PASCAL FROM "_FreeImage_Load@12" LIB hLib
DLL32 STATIC FUNCTION FIGETFILETYPE( cFileName AS LPSTR, nSize AS LONG )AS LONG;
PASCAL FROM "_FreeImage_GetFileType@8" LIB hLib
DLL32 STATIC FUNCTION FISAVE( nFormat AS LONG, hDib AS LONG, cFileName AS LPSTR, nFlags AS LONG ) AS BOOL;
PASCAL FROM "_FreeImage_Save@16" LIB hLib
Pues mas o menos es esto. Parte la he sacado de una contribución que hizo Rafa Carmona. (Saludos Rafacarmona)
Un saludo
http://www.google.es/search?hl=es&q=freeimage&meta=
- Rafael Clemente
- Posts: 365
- Joined: Sat Oct 08, 2005 7:59 pm
- Location: Barcelona, Spain