Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Otros entornos y lenguajes > C++ Builder
Registrarse FAQ Miembros Calendario Guía de estilo Buscar Temas de Hoy Marcar Foros Como Leídos

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 02-04-2008
fasthorse fasthorse is offline
Miembro
 
Registrado: ene 2007
Posts: 90
Poder: 18
fasthorse Va por buen camino
Selección de una imagen

Hola, alguien sabe si el componente TImage tiene alguna propiedad que permita seleccionar parte de la imagen? y ya hacer con esa selección varias operaciones?

Saludos y gracias.
Responder Con Cita
  #2  
Antiguo 02-04-2008
Avatar de cHackAll
[cHackAll] cHackAll is offline
Baneado?
 
Registrado: oct 2006
Posts: 2.159
Poder: 20
cHackAll Va por buen camino
No hay tal cosa, pero lo que se hace es un buffer doble copiando la seleccion que es una Recta con CopyRect hacia un Bitmap o Canvas temporal, luego de realizar los cambios volver a copiar la Recta a su lugar de origen ya modificada.

Saludos
Responder Con Cita
  #3  
Antiguo 02-04-2008
fasthorse fasthorse is offline
Miembro
 
Registrado: ene 2007
Posts: 90
Poder: 18
fasthorse Va por buen camino
ok, pero esa selección como la dibujo? con un TShape, por ejemplo? o hay algún otro componente más adecuado para tal?

Gracias, saludos.
Responder Con Cita
  #4  
Antiguo 02-04-2008
Avatar de cHackAll
[cHackAll] cHackAll is offline
Baneado?
 
Registrado: oct 2006
Posts: 2.159
Poder: 20
cHackAll Va por buen camino
Si
Código:
 TShape->Brush->Style = bsClear;
 TShape->Pen->Style = psDot;
Responder Con Cita
  #5  
Antiguo 02-04-2008
fasthorse fasthorse is offline
Miembro
 
Registrado: ene 2007
Posts: 90
Poder: 18
fasthorse Va por buen camino
Ah no! creo que antes te he entendido mal, te refieres a que haga la misma selección con el Rect, no? por ejemplo si quiero seleccionar todo la imagen sería algo así:

RECT Area;
Area = ClientRect;

y ahora copiaría el área a un canvas por ejemplo?
canvas->CopyMode ?

Gracias.
Responder Con Cita
  #6  
Antiguo 02-04-2008
Avatar de cHackAll
[cHackAll] cHackAll is offline
Baneado?
 
Registrado: oct 2006
Posts: 2.159
Poder: 20
cHackAll Va por buen camino
Post #2, para la idea general
Post #4, para efecto visual

Búsqueda para ejemplos de uso del método CopyRect.

Saludos
Responder Con Cita
  #7  
Antiguo 03-04-2008
fasthorse fasthorse is offline
Miembro
 
Registrado: ene 2007
Posts: 90
Poder: 18
fasthorse Va por buen camino
ok, ya tengo hecha la selección y se más o menos como se haría el CopyMode, pero quisiera que el usuario pueda mover y redimensionar la selección que sale por defecto. ¿Cómo se haría esto?

Un saludo.
Responder Con Cita
  #8  
Antiguo 03-04-2008
fasthorse fasthorse is offline
Miembro
 
Registrado: ene 2007
Posts: 90
Poder: 18
fasthorse Va por buen camino
Estoy mirando a ver si puede ser con unas opciones del TShape que son onDragOver y onDragDrop que son de arrastrar y soltar, pero no me hacen nada... y con respecto a lo de la redimensión no se aún cómo hacerlo.
Aunque alguna forma habrá no?

Saludos.
Responder Con Cita
  #9  
Antiguo 03-04-2008
Avatar de cHackAll
[cHackAll] cHackAll is offline
Baneado?
 
Registrado: oct 2006
Posts: 2.159
Poder: 20
cHackAll Va por buen camino
Cita:
Empezado por fasthorse Ver Mensaje
Aunque alguna forma habrá no?
Debes usar el evento OnMouseDown, OnMouseUp y OnMouseMove tanto de la TImage como del TShape para controlar la seleccion.

En el OnMouseDown defines el Left y Top del TShape, y en el OnMouseMove defines el Right, Button del mismo hasta que sea llamado el evento OnMouseUp; ésto te dará el efecto necesario.

Saludos
Responder Con Cita
  #10  
Antiguo 03-04-2008
fasthorse fasthorse is offline
Miembro
 
Registrado: ene 2007
Posts: 90
Poder: 18
fasthorse Va por buen camino
Hola, me podrías poner por favor, un ejemplo del uso de los eventos OnMouseDown, OnMouseUp y OnMouseMove, y cómo dentro de ellos les indico el valor de Letf, top...? No se muy bien cómo hacerlos.

Gracias, saludos.
Responder Con Cita
  #11  
Antiguo 03-04-2008
[egostar] egostar is offline
Registrado
 
Registrado: feb 2006
Posts: 6.556
Poder: 25
egostar Va camino a la fama
Cita:
Empezado por fasthorse Ver Mensaje
Hola, me podrías poner por favor, un ejemplo del uso de los eventos OnMouseDown, OnMouseUp y OnMouseMove, y cómo dentro de ellos les indico el valor de Letf, top...? No se muy bien cómo hacerlos.

Gracias, saludos.
Hola fasthorse, para estos casos lo mejor es usar la famosisima tecla F1 y ver los ejemplos que te proporciona.

Salud OS
__________________
"La forma de empezar es dejar de hablar y empezar a hacerlo." - Walt Disney
Responder Con Cita
  #12  
Antiguo 04-04-2008
Avatar de escafandra
[escafandra] escafandra is offline
Miembro Premium
 
Registrado: nov 2007
Posts: 2.195
Poder: 20
escafandra Tiene un aura espectacularescafandra Tiene un aura espectacular
Hace cuatro semanas iniciaste este mismo tema. Recuerda esto:
Cita:
Empezado por escafandra Ver Mensaje
Investiga esto:
Canvas->Rectangle y InvalidateRect http://msdn2.microsoft.com/en-us/library/ms534893.aspx
Utiliza también el evento OnMouseMove y OnMouseClick para mover y cambiar el tamaño de tu rectángulo.
Utiliza eventos de teclado para controlar acciones de las teclas Control y Alt.

Saludos.
Canvas->Rectangle dibuja un rectángulo en dicho canvas, sin necesidad de utilizar componentes visuales como TShape. Puedes dibujarlo en línea contínua, puntitos... InvalidateRect te sirva para repintar el área original cada vez que muevas o modifiques tu rectángulo selector.

Para que invalidateRect funcione mejor, haz una llamada por cada lado del rectángulo, de esa forma el área de éste no se repinta entera y el efecto visual es mejor.

Evidentemente el control de ese rectángulo, lo haces con el ratón con los eventos descritos.

Crea una variable o b¡miembro de la clase que almacene el TRect "selector" para que los eventos del ratón la modifiquen según su movimiento (OnMouseMove y OnMouseClick).

Investiga la ayuda de Builder.
Responder Con Cita
  #13  
Antiguo 05-04-2008
fasthorse fasthorse is offline
Miembro
 
Registrado: ene 2007
Posts: 90
Poder: 18
fasthorse Va por buen camino
Ok, hago dibujando con el Canvas, en vez de utilizar un Tshape como me dices, pero ahora resulta que en la ejecución me dice : "can only modify an image if it contain a bitmap". la tendría que convertir a Bitmap para poder manipularla? si el caso es afirmativo, como seria?

Gracias.
Responder Con Cita
  #14  
Antiguo 05-04-2008
Avatar de escafandra
[escafandra] escafandra is offline
Miembro Premium
 
Registrado: nov 2007
Posts: 2.195
Poder: 20
escafandra Tiene un aura espectacularescafandra Tiene un aura espectacular
Pues ahora no entiendo muy bien lo que quieres hacer. Lo que te propuse era dibujar un rectángulo que representa el área seleccionada. Esto es lo que entendí que querías hacer. Modificar el tamaño de ese rectángulo, moverlo... Para al terminar, tener unas coordenadas en un TRect que posteriormente usarías para copiar parte de la imagen.

Si lo que pretendes es modificar directamente la imagen, en tiempo real al mover el ratón, la cosa cambia.

No se como has dibujado en el canvas.

Si tratas de dibujar en un control al que no tienea acceso a su canvas, pues haces lo siguente:



Código:
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
   : TForm(Owner)
{
   // Si tratas de dibujar en un control al que no tienea acceso a su canvas, pues haces lo siguente:
   // En la definición de TForm1 defines  TControlCanvas*   Canvas; //Sobrecargado...
   // En el Constructor:
   // Canvas = new TControlCanvas;
   // Canvas->Control = this;

    Canvas->Pen->Mode = pmNot;
    Canvas->Pen->Style = psDot;
    Canvas->Pen->Width = 1;
    Canvas->Brush->Style = bsClear; //bsDiagCross;
 
    // Variable con la selección TRect SelectRect;
    SelectRect = TRect(0,0,0,0);    
}

//---------------------------------------------------------------------------
__fastcall TForm1::~TForm1(TComponent* Owner)
   : TForm(Owner)
{
   // Si tratas de dibujar en un control al que no tienea acceso a su canvas, pues haces lo siguente:
    // delete Canvas;

//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
   SelectRect = TRect(100,100,200,200);

   Canvas->Rectangle(SelectRect);
}
Cada vez que modificas el rectángulo, lo tienes que borrar y repintar. Para borrar: InvalidateRect.

Una forma de agilizar el tema, si el efecto visual de repintar el área del rectángulo no te gusta sería escribir otra función que sólo borre los lados del rectángulo:

Código:
void InvalidateFrameRect(TWinControl *Control, TCanvas *Canvas, TRect Rect)
{
   int H = Canvas->Pen->Width/2 + 1;

   // Normalizamos el TRect
   Rect = TRect(min(Rect.Left, Rect.Right), min(Rect.Top, Rect.Bottom),
                max(Rect.Left, Rect.Right), max(Rect.Top, Rect.Bottom));
  
   TRect R(Rect.Left-H, Rect.Top-H, Rect.Right+H, Rect.Top+H);
   InvalidateRect(Control->Handle, &R, true);
   R = TRect(Rect.Left-H, Rect.Bottom-H, Rect.Right+H, Rect.Bottom+H);
   InvalidateRect(Control->Handle, &R, true);
   R = TRect(Rect.Left-H, Rect.Top-H, Rect.Left+H, Rect.Bottom+H);
   InvalidateRect(Control->Handle, &R, true);
   R = TRect(Rect.Right-H, Rect.Top-H, Rect.Right+H, Rect.Bottom+H);
   InvalidateRect(Control->Handle, &R, true);


   Control->Perform(WM_PAINT, (int)Canvas->Handle, 0);
   Control->Update();
}
LLevas una variable de la clase TForm (o la que sea) que sea un TRect con las coordenadas de tu selección que son a su vez la de tu rectángulo selecionador...
El resto lo haces con los eventos del ratón (OnMouseDown, OnMouseUp y OnMouseMove) a los que puedes añadir modificadores con el teclado (TShiftState) o lo que necesites.

Si prefieres hacerlo con un TShape, pues también te sirve, como bien te indicó cHackAll.

Espero que te sirva de ayuda.

Saludos.



EDITO 2:
Corrijo un pequeño fallo, se debe normalizar el TRect.

Te muestro un ejemplo: Archivo Adjunto 1220

Última edición por escafandra fecha: 21-05-2008 a las 13:09:51.
Responder Con Cita
  #15  
Antiguo 05-04-2008
fasthorse fasthorse is offline
Miembro
 
Registrado: ene 2007
Posts: 90
Poder: 18
fasthorse Va por buen camino
Si, en general yo quiero que la seleccione para luego operar con ella, ya sea para modificarla directamente, como puedo ser por ejemplo cambiar el color de la parte seleccionada, y también para las típicas operacion de copiar, cortar y pegar...

Me está sirviendo mucho toda la información que me has dado, pero me sigue dando el mismo error que antes comenté... "can only modify if it contains a bitmap". La imagen que abro es jpg, sin embargo si abro una imagen bmp no me da problemas, si me pinta el rectangulo. ¿Qué puedo hacer para que también lo haga con las imágene jpg?

Gracias.
Responder Con Cita
  #16  
Antiguo 06-04-2008
Avatar de escafandra
[escafandra] escafandra is offline
Miembro Premium
 
Registrado: nov 2007
Posts: 2.195
Poder: 20
escafandra Tiene un aura espectacularescafandra Tiene un aura espectacular
¿Sobre que tipo de control quieres colocar tu rectángulo seleccionador?. Me da la impresión que es sobre un TImage. En ese caso tienes que cambiar alguna cosa. El ejemplo que puse es para una ventana sin mas.

Mira esto: Archivo Adjunto 1222

PD No puedo mantener mucho tiempo los archivos subidos pues mi cuota esta casi al límite.

Última edición por escafandra fecha: 21-05-2008 a las 13:09:51.
Responder Con Cita
  #17  
Antiguo 07-04-2008
fasthorse fasthorse is offline
Miembro
 
Registrado: ene 2007
Posts: 90
Poder: 18
fasthorse Va por buen camino
ok, ya lo tengo descargado, voy a ponerme con ello.

Muchas gracias.
Responder Con Cita
  #18  
Antiguo 08-04-2008
fasthorse fasthorse is offline
Miembro
 
Registrado: ene 2007
Posts: 90
Poder: 18
fasthorse Va por buen camino
Si, quiero colocar mi rectángulo seleccionador sobre el TImage, una vez visto el ejemplo, me surge una duda... corregidme si no estoy en lo cierto, a ver...
yo tengo una funcion (boton seleccionar) donde dibujo el rectángulo... y creo que es de allí dónde tengo que llamar a lós métodos de FormMouse Down y demás... tendría:

void __fastcall TForm1::ToolButton5Click(TObject *Sender) //seleccionar
//un trozo d imagen
{
TRect *SelectRect;
SelectRect= new TRect(100,100,200,200);
Imagen->Canvas->Rectangle(100,100,200,200);

//hasta aquí dibujo el rectángulo, y ahora tendría que llamar o hacer alguna referencia a los métodos del ratón... pero cómo los llamo desde aqui???
Imagen->FormMouseDown(); //algo asi?? pero es que realmente el FormMouseDown() no es un método de Imagen...
y en qué orden las tendría que llamar??
}

Gracias, saludos
Responder Con Cita
  #19  
Antiguo 09-04-2008
Avatar de escafandra
[escafandra] escafandra is offline
Miembro Premium
 
Registrado: nov 2007
Posts: 2.195
Poder: 20
escafandra Tiene un aura espectacularescafandra Tiene un aura espectacular
En el ejemplo, los eventos del ratón, los maneja el propio formulario, aunque si te fijas, son eventos producidos por TImage. La función que maneja un evento, no suele ser miembro de la ventana que lo provoca, sino del formulario, de esa forma las VCL facilitan el no tener que derivar una clase de cada ventana que se use. En general esto es así a no ser que estemos programado un control.

Por otra parte no se si te has fijado que el canvas utilizado para pintar tu rectángulo no es el del TImage sino el del propio formulario. Con esto evitamos el parpadeo que aveces aparece al pintar en un TImage.

Esta expresión no deberías usarla:
Código:
TRect *SelectRect;
SelectRect= new TRect(100,100,200,200);
Esto te obliga a destruir explicitamente el TRect, una vez usado:

Código:
TRect *SelectRect = new TRect(100,100,200,200);
.
.
.
delete SelectRect;
Como TRect no pertenece a la estructura de clases de la VCL propiamente dicha, no estás obligado a usar punteros, asi que es mas fácil esto:

Código:
   TRect SelectRect(100,100,200,200);
¿No te parece?. No creas un puntero a un objeto, sino el objeto directamente.

Los Eventos del raton no los llamas tu, se producen al utilizar el ratón. Tu puedes controlarlos. Si no quieres que tu rectángulo selector se pinte hasta que no pulses previamente un botón, coloca una bandera en el evento, para que no se ejecute si no es verdadera.

Código:
Form1::Button1Click(..){
  Seleccionar = true; // Seleccionar es una variable global tipo bool usasa como bandera.
}

Form1::OnMouseMove(...){
    if(Selecionar){

      //Resto del evento.
   }
}

Form1::OnMouseDown(...){
    if(Selecionar){

      //Resto del evento.
   }
}
Form1::OnMouseUp(...){
     if(Selecionar){
 
       //Resto del evento.
    }
}
¿Me explico?.

Un buen ejercicio sería programar todo esto de la selección como un componente visual que incrustes en un formulario y al que asignes una propiedad de tipo control donde pintarás tu rectángulo selector.

Saludos.

Última edición por escafandra fecha: 09-04-2008 a las 00:52:49.
Responder Con Cita
  #20  
Antiguo 09-04-2008
fasthorse fasthorse is offline
Miembro
 
Registrado: ene 2007
Posts: 90
Poder: 18
fasthorse Va por buen camino
Hola, si, te has explicado muy bien, pero sigue sin salirme, llego a dibujar el rectángulo, pero no consigo moverlo ni cambiarlo de tamaño, ni hacer nada con él. Te pongo el código de lo que llevo, a ver si le vemos algo, le puse la variable bool seleccionar como me indicaste:

//defino la variable como global
bool seleccionar;

void __fastcall TForm1::ToolButton5Click(TObject *Sender) //seleccionar
//un trozo d imagen
{
seleccionar=true;
TRect SelectRect(100,100,200,200);
Imagen->Canvas->Brush->Style=bsClear;
Imagen->Canvas->Pen->Style=psDot;
Imagen->Canvas->Rectangle(SelectRect);

}

void InvalidateFrameRect(TControl *Control, TCanvas *Canvas, TRect Rect)
{
if(seleccionar){
InvalidateRect(Canvas->Handle, &Rect, true);
Control->Perform(WM_PAINT, (int)Canvas->Handle, 0);
}
}
//----------------------------------------------------------------------------
void __fastcall TForm1::FormMouseDown(TObject *Sender, TMouseButton Button,
TShiftState Shift, int X, int Y)
{
if(seleccionar){
AccionPoint = TPoint(X+Imagen->Left,Y+Imagen->Top);
}
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormMouseMove(TObject *Sender, TShiftState Shift,
int X, int Y)
{
if(seleccionar){
if(AccionPoint.x!=-1 && AccionPoint.y!= -1 && Imagen->Picture->Graphic) {
InvalidateFrameRect(this, Canvas, SelectRect);
if(X<0) X=0; if(X>Imagen->Width) X = Imagen->Width;
if(Y<0) Y=0; if(Y>Imagen->Height) Y = Imagen->Height;
X += Imagen->Left;
Y += Imagen->Top;
SelectRect = TRect(AccionPoint.x, AccionPoint.y, X, Y);
SelectRect = TRect(min(SelectRect.Left, SelectRect.Right), min(SelectRect.Top, SelectRect.Bottom),
max(SelectRect.Left, SelectRect.Right), max(SelectRect.Top, SelectRect.Bottom));
Canvas->Rectangle(SelectRect);
}
}
}
//------------------------------------------------------------------------------------------------
void __fastcall TForm1::FormMouseUp(TObject *Sender, TMouseButton Button,
TShiftState Shift, int X, int Y)
{
if(seleccionar){
AccionPoint = TPoint(-1,-1);
}
}

He probado escribiendo algún que otro ShowMessage... y no se mete en ninguno de los métodos del ratón....

¿qué es lo q me falta?

saludos.
Responder Con Cita
Respuesta


Herramientas Buscar en Tema
Buscar en Tema:

Búsqueda Avanzada
Desplegado

Normas de Publicación
no Puedes crear nuevos temas
no Puedes responder a temas
no Puedes adjuntar archivos
no Puedes editar tus mensajes

El código vB está habilitado
Las caritas están habilitado
Código [IMG] está habilitado
Código HTML está deshabilitado
Saltar a Foro

Temas Similares
Tema Autor Foro Respuestas Último mensaje
Selección en Excel Jordy Servers 1 06-12-2005 09:55:00
Selección de figuras Luli Gráficos 8 01-12-2004 12:08:49
seleccion dbgrid davidgaldo Conexión con bases de datos 3 26-02-2004 10:45:33
Seleccion en DBLookUpComboBox NuncaMas Varios 1 22-12-2003 19:41:21
una seleccion YolandaM Impresión 2 04-10-2003 21:11:59


La franja horaria es GMT +2. Ahora son las 03:56:13.


Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi
Copyright 1996-2007 Club Delphi