Cómo dibujar un rectángulo de tamaño ajustable

Cómo dibujar un rectángulo de tamaño ajustable

Postby Rafael Clemente » Tue Feb 07, 2006 1:19 pm

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
User avatar
Rafael Clemente
 
Posts: 365
Joined: Sat Oct 08, 2005 7:59 pm
Location: Barcelona, Spain

Postby Antonio Linares » Tue Feb 07, 2006 6:56 pm

Rafael,

Tienes un ejemplo en visual\design.prg en concreto los métodos:
METHOD LButtonDown( nRow, nCol, nFlags )
METHOD LButtonUp( nRow, nCol, nFlags )
METHOD MouseMove( nRow, nCol, nFlags )
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Antonio Linares
Site Admin
 
Posts: 42122
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain

Postby Rafael Clemente » Tue Feb 07, 2006 7:32 pm

Antonio:
He revisado todas mis versiones de FWH (desde la 2.4 hasta la 2.6) y en ninguna encuentro Samples\visual\design.prg. Me podrías enviar una copia de ese programa, por favor?
Gracias
Rafael
User avatar
Rafael Clemente
 
Posts: 365
Joined: Sat Oct 08, 2005 7:59 pm
Location: Barcelona, Spain

Postby Rafael Clemente » Tue Feb 07, 2006 7:40 pm

Antonio:
No te molestes. Según indicaciones de James Bott, acabo de encontrarlo en mi antiguo directorio de FW. Voy a estudiármelo. Gracias
Rafael
User avatar
Rafael Clemente
 
Posts: 365
Joined: Sat Oct 08, 2005 7:59 pm
Location: Barcelona, Spain

Postby reinaldocrespo » Tue Feb 07, 2006 9:41 pm

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.
User avatar
reinaldocrespo
 
Posts: 979
Joined: Thu Nov 17, 2005 5:49 pm
Location: Fort Lauderdale, FL

Postby Rafael Clemente » Tue Feb 07, 2006 10:00 pm

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
User avatar
Rafael Clemente
 
Posts: 365
Joined: Sat Oct 08, 2005 7:59 pm
Location: Barcelona, Spain

Postby reinaldocrespo » Tue Feb 07, 2006 10:16 pm

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.

Code: Select all  Expand view  RUN
//----------------------------------------------------------------------------//

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


No se si esto te ayuda.

Reinaldo.
User avatar
reinaldocrespo
 
Posts: 979
Joined: Thu Nov 17, 2005 5:49 pm
Location: Fort Lauderdale, FL

Postby Rafael Clemente » Tue Feb 07, 2006 10:59 pm

Reinaldo:
Déjame que lo prueba. Ahora ya es muy tarde. Mañana te digo algo pero creo que podremos encontrar una solución.
Un saludo,
Rafael
User avatar
Rafael Clemente
 
Posts: 365
Joined: Sat Oct 08, 2005 7:59 pm
Location: Barcelona, Spain

DrawFocusRect

Postby Paco Garcia » Tue Feb 07, 2006 11:15 pm

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.

Code: Select all  Expand view  RUN
#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
User avatar
Paco Garcia
 
Posts: 172
Joined: Fri Oct 07, 2005 12:00 pm

Paco: Problema resuelto

Postby Rafael Clemente » Wed Feb 08, 2006 3:24 pm

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
User avatar
Rafael Clemente
 
Posts: 365
Joined: Sat Oct 08, 2005 7:59 pm
Location: Barcelona, Spain

Postby Rafael Clemente » Wed Feb 08, 2006 3:40 pm

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/en_nconvert.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  Expand view  RUN
WaitRun('nconvert -out bmp -crop ' + STR(x1) + STR(y1) + STR(x2-x1+1) + STR(y2-y1+1) + '-quiet -o Recorte.bmp "FotoOrig.bmp"', 0)

y ya está.
Yo te he puesto el ejemplo en formato Bmp, pero puedes trabajar en cualquier otro.
Un saludo,
Rafael
User avatar
Rafael Clemente
 
Posts: 365
Joined: Sat Oct 08, 2005 7:59 pm
Location: Barcelona, Spain

Postby Paco Garcia » Wed Feb 08, 2006 9:41 pm

Hola Rafael.

Cualquier método es bueno si consigues tu meta pero es un poco matar moscas a cañonazos.

A ver que te parece esto:

Code: Select all  Expand view  RUN

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



Un saludo
User avatar
Paco Garcia
 
Posts: 172
Joined: Fri Oct 07, 2005 12:00 pm

Postby Rafael Clemente » Wed Feb 08, 2006 9:50 pm

Paco:
Lo probaré. Desde luego, estoy de acuerdo en que es mucho más elegante que lo de nConvert.
Ahora bien, yo no suelo utilizar Bmps sino Tiff y Jpg. ¿Te parece que sería posible algo semejante para esos formatos?
Rafael
User avatar
Rafael Clemente
 
Posts: 365
Joined: Sat Oct 08, 2005 7:59 pm
Location: Barcelona, Spain

Postby Paco Garcia » Thu Feb 09, 2006 8:40 am

Pues si mire "uste" :D

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  Expand view  RUN

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=
User avatar
Paco Garcia
 
Posts: 172
Joined: Fri Oct 07, 2005 12:00 pm

Postby Rafael Clemente » Thu Feb 09, 2006 8:49 am

Paco:
Pues no tenía ni idea de que pudiera ser tan fácil... :oops:
Me miraré la documentación que encuentre del FreeImage a ver qué otras maravillas salen por ahí.
Muchíiisimas gracias, Paco!
Rafael
User avatar
Rafael Clemente
 
Posts: 365
Joined: Sat Oct 08, 2005 7:59 pm
Location: Barcelona, Spain

Next

Return to FiveWin para Harbour/xHarbour

Who is online

Users browsing this forum: Google [Bot] and 37 guests