Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   OOP (https://www.clubdelphi.com/foros/forumdisplay.php?f=5)
-   -   Centrar ellipse en TImage (https://www.clubdelphi.com/foros/showthread.php?t=94471)

compuin 26-02-2020 03:02:52

Centrar ellipse en TImage
 
Buenas noches foro

Estoy tratando de colocar un circulo a traves de una ellipse en un TImage pero por mas que lo intento no logro que me quede completamente centrado

El TImage tiene estas dimensiones

Código Delphi [-]
  FormMain.Wheel.Top := 10;
  FormMain.Wheel.left:= 250;
  FormMain.Wheel.Height:= 650;
  FormMain.Wheel.Width:= 1000;


En cuanto al circulo, lo estoy realizando con estas dimensiones

Código Delphi [-]
Ellipse( 17, 17, 674, 674 );

Segun he leido, los 2 ultimos valores son el alto y largo del circulo pero con los 2 primeros trato de posicionarlo en el centro del TImage pero no funciona. So estos valores como una coordenada?

Cual es la manera correcta de posicionarlo?

Gracias de antemano

kuan-yiu 26-02-2020 08:54:07

La única vez que hice algo parecido los parámetros indicaban otra cosa: las coordenadas del rectángulo en el que está inscrita la elipse, vértice superior izquierdo, vértice inferior derecho.
Código Delphi [-]
Ellipse(0, 0, dibujo.Width, dibujo.Height);
Supongo que ese procedimiento estará sobrecargado, asegúrate de estar usando la versión que te interesa o prueba otra a ver si se ajusta más a lo que necesitas.

Neftali [Germán.Estévez] 26-02-2020 09:12:31

En estos casos el refrán de, "Una imagen vale más que 1000 palabras", vendría muy bien.
;););)
También me queda la duda de si el procedimiento que estás utilizando es el de TCanvas.

compuin 26-02-2020 12:29:43

Cita:

Empezado por Neftali [Germán.Estévez] (Mensaje 535916)
En estos casos el refrán de, "Una imagen vale más que 1000 palabras", vendría muy bien.
;););)
También me queda la duda de si el procedimiento que estás utilizando es el de TCanvas.

Si, utilizo TCanvas

En un instante subo la imagen

Neftali [Germán.Estévez] 26-02-2020 13:23:27

Si usas el camvas de la imagen, puedes usar algo como esto:


Código Delphi [-]
  Wheel.Canvas.Pen.Color := clRed;
  Ellipse(Wheel.Canvas.Handle, 0, 0, Wheel.Width, Wheel.Height);


Si usas el del formulario, tendrás que ajustar esas coordenadas.

compuin 26-02-2020 13:33:53

Aca la imagen


compuin 26-02-2020 14:17:28

Cita:

Empezado por Neftali [Germán.Estévez] (Mensaje 535922)
Si usas el camvas de la imagen, puedes usar algo como esto:


Código Delphi [-]
  Wheel.Canvas.Pen.Color := clRed;
  Ellipse(Wheel.Canvas.Handle, 0, 0, Wheel.Width, Wheel.Height);


Si usas el del formulario, tendrás que ajustar esas coordenadas.


Con este codigo aun no logra centrar el circulo

Neftali [Germán.Estévez] 26-02-2020 14:56:00

A mi me sale centrado.
En negrio el original, en rojo el que te he puesto.



compuin 26-02-2020 15:02:38

Ok,

Agregandolo asi me dice "too many actual parameters"

Código Delphi [-]
    FormMain.Wheel.Canvas.Pen.Color := clRed;
    Ellipse(formmain.Wheel.Canvas.Handle, 0, 0, formmain.Wheel.Width, formmain.Wheel.Height);

Neftali [Germán.Estévez] 26-02-2020 15:10:18

1 Archivos Adjunto(s)
¿Puedes poner un poco más de código?
Es que no se dónde estás poniendo esas líneas. ¿Dentro del formulario FormMain? ¿En otra Unit? ¿Estás usando eso dentro de un With?

Te adjunto el ejemplo.

compuin 26-02-2020 15:15:51

En otra Unit

La unit donde esta definido el formulario se llama Unit1

El formulario es asi

Código Delphi [-]
var
  FormMain: TFormMain;

El image es asi

Código Delphi [-]
Wheel: TImage;

El codigo para crear la rueda esta en una unit que se llama charts

Y el codigo para tratar de crearla es

Código Delphi [-]
  with FormMain.Wheel.Canvas do
  begin
    FormMain.Wheel.Canvas.Pen.Color := clRed;
    Ellipse(formmain.Wheel.Canvas.Handle, 0, 0, formmain.Wheel.Width, formmain.Wheel.Height);
end;


Espero haberme hecho entender mejor :)

Neftali [Germán.Estévez] 26-02-2020 15:34:51

Elimina el primer parámetro.
Todo el problema lo rienes por meter esas líneas dntro de un with.

Te está cogiendo el Ellipse del Canvas de TImage.


La otra opción es dejar el with y colocar esto:


Código Delphi [-]
    Winapi.Windows.Ellipse(form1.Wheel.Canvas.Handle, 0, 0, form1.Wheel.Width, form1.Wheel.Height);


Con eso te compilará bien.

compuin 26-02-2020 15:36:55

Gracias Neftali

No se si sirva de algo pero estoy utilizando Borland Delphi 7, asi que algunas instrucciones no me estan funcionando adecuadamente

compuin 26-02-2020 15:38:43

Cita:

Empezado por Neftali [Germán.Estévez] (Mensaje 535931)
Elimina el primer parámetro.
Todo el problema lo rienes por meter esas líneas dntro de un with.

Te está cogiendo el Ellipse del Canvas de TImage.


La otra opción es dejar el with y colocar esto:


Código Delphi [-]
    Winapi.Windows.Ellipse(form1.Wheel.Canvas.Handle, 0, 0, form1.Wheel.Width, form1.Wheel.Height);


Con eso te compilará bien.

Me arroja este error

: Too many actual parameters

ecfisa 26-02-2020 16:21:49

Hola.

Fijate si te sirve de este modo:
Código Delphi [-]
procedure CenterEllipse(Img: TImage; x1,y1,x2,y2: Integer; aColor: TColor);
var
  C,R: TPoint;
begin
  C.X := (Img.Picture.Width) div 2;
  C.Y := (Img.Picture.Height) div 2;
  R.X := (x2-x1) div 2 ;
  R.Y := (y2-y1) div 2;
  if (C.X-R.X < 0) or (C.Y-R.Y < 0) or
     (C.X+R.X > Img.Picture.Width) or (C.Y+R.Y >Img.Picture.Height) then
    raise Exception.Create('Elipse fuera de rango');

  Img.Canvas.Pen.Color := aColor;
  Img.Canvas.Ellipse(C.X - R.X,  C.Y - R.Y, C.X + R.X, C.Y + R.Y);
end;
Ejemplo de llamada:
Código Delphi [-]
procedure TForm1.Button1Click(Sender: TObject);
begin
  CenterEllipse(Image1, 17, 17, 528, 528, clBlack);
end;

Salida:


Saludos :)

compuin 26-02-2020 16:39:28

Hola

Me esta dando este error


ecfisa 26-02-2020 17:24:01

Hola.

Cambiá por ShowMessage, v.gr. :
Código Delphi [-]
procedure TForm1.FormCreate(Sender: TObject);
begin
  Image1.Picture.LoadFromFile(GetEnvironmentVariable('HOMEPATH')+'\Pictures\Blank.bmp');
end;

procedure CenterEllipse(Img: TImage; x1,y1,x2,y2: Integer; aColor: TColor);
var
  C,R: TPoint;
begin
  C.X := (Img.Picture.Width) div 2;
  C.Y := (Img.Picture.Height) div 2;
  R.X := (x2-x1) div 2 ;
  R.Y := (y2-y1) div 2;
  if (C.X-R.X < 0) or (C.Y-R.Y < 0) or
     (C.X+R.X > Img.Picture.Width) or (C.Y+R.Y >Img.Picture.Height) then
    ShowMessage('Elipse fuera de rango')
  else
  begin
    Img.Canvas.Pen.Color := aColor;
    Img.Canvas.Ellipse(C.X - R.X,  C.Y - R.Y, C.X + R.X, C.Y + R.Y);
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  CenterEllipse(Image1, 17, 17, 328, 328, clRed);
end;

Saludos :)

compuin 26-02-2020 17:26:56

Gracias,

Ahora solo muestra el mensaje pero no el TImage ni el circulo


ecfisa 26-02-2020 17:41:32

Hola.

Y... ¿ No estará fuera del rango ?

Si no te importa que se corte el ellipse, eliminá las líneas de comprobación de este modo:
Código Delphi [-]
procedure CenterEllipse(Img: TImage; x1,y1,x2,y2: Integer; aColor: TColor);
var
  C,R: TPoint;
begin
  C.X := (Img.Picture.Width) div 2;
  C.Y := (Img.Picture.Height) div 2;
  R.X := (x2-x1) div 2 ;
  R.Y := (y2-y1) div 2;
  Img.Canvas.Pen.Color := aColor;
  Img.Canvas.Ellipse(C.X - R.X,  C.Y - R.Y, C.X + R.X, C.Y + R.Y);
end;

Saludos :)

compuin 26-02-2020 17:42:36

Como le establezo el rango ?

ecfisa 26-02-2020 17:48:23

Hola.

A ver, si tenes una imágen de 10 x 10 y dibujas un círculo de 15 x 15 es seguro que no se va a enmarcar en el primero. Lo normal es que el lienzo donde dibujas, sea superior a la imágen que intentas dibujar. De allí la verificación del if ... then y el consiguiente mensaje.

Pero todo eso si interpreté bién lo que estas buscando hacer...

Saludos :)

compuin 26-02-2020 17:50:56

Pues ni reduciendole las dimensiones al elipse me funciona

ecfisa 26-02-2020 18:06:26

1 Archivos Adjunto(s)
Hola.

Funciona correcto en mi caso.

Lamento no tener Delphi 7 pero despues de haberlo usado por cerca de dos décadas te puedo asegurar que el código funcionará en esa versión también.

Lo mas que puedo hacer es adjuntarte el código funcionando en Delphi 10.3 para que puedas extraer de allí lo que te sirva.

Solo crea una carpeta y extraé el comprimido allí.

Saludos :)

Neftali [Germán.Estévez] 26-02-2020 21:01:39

1 Archivos Adjunto(s)
Cita:

Empezado por compuin (Mensaje 535932)
Gracias Neftali
No se si sirva de algo pero estoy utilizando Borland Delphi 7, asi que algunas instrucciones no me estan funcionando adecuadamente


Es muy similar, lo único que cambian son las units.
Este que te adjunto está en Delphi7 y funciona.

compuin 26-02-2020 21:04:35

Hola neptali,

Ya probe el ejemplo que me enviastes para D7 pero este no queda circular y sus bordes quedan pegados a los bordes del TImage

:confused:

compuin 26-02-2020 21:10:44


Neftali [Germán.Estévez] 26-02-2020 23:03:27

1 Archivos Adjunto(s)
Cita:

Empezado por compuin (Mensaje 535957)
Hola neptali,

Ya probe el ejemplo que me enviastes para D7 pero este no queda circular y sus bordes quedan pegados a los bordes del TImage

Vaya, pensé que eso era lo que querías. :(:(:(
Con unas pequeñas modificaciones en los puntos de dibujo debería centrarse.

NOTA:el código del ejemplo de puede optimizar para eliminar operaciones repetidas.

compuin 27-02-2020 00:07:37

Ya lo intente no tuve exito

ecfisa 27-02-2020 00:26:12

Hola.
Cita:

Empezado por compuin (Mensaje 535963)
Ya lo intente no tuve exito

Adjunta el código que te dá problemas tál como lo compilas.

Saludos :)

compuin 27-02-2020 01:15:29

Este mensaje era del elipse antes de recibir el ultim codigo que me enviastes

Esta perfecto dibuja un circulo centrado en el TImage

Que debo modificar para hacerlo mas pequeno y que me deje espacio entre los bordes superiores e inferiores del TImage sin perder la circunferencia, es decir, reducir el diametro del circulo ?


Neftali [Germán.Estévez] 27-02-2020 08:29:12

Cita:

Empezado por compuin (Mensaje 535965)
Que debo modificar para hacerlo mas pequeno y que me deje espacio entre los bordes superiores e inferiores del TImage sin perder la circunferencia, es decir, reducir el diametro del circulo ?


La imagen que has colocado no se ve.
Si necesitas un margen en el círculo, sólo debes sumarselo a las 2 primeras Coordenadas (x1, y1) y restárselo a las 2 segundas (x2, y2).

compuin 27-02-2020 12:29:45

Cita:

Empezado por Neftali [Germán.Estévez] (Mensaje 535967)
La imagen que has colocado no se ve.
Si necesitas un margen en el círculo, sólo debes sumarselo a las 2 primeras Coordenadas (x1, y1) y restárselo a las 2 segundas (x2, y2).

Necesito hacer el círculo más pequeño y que no toque los bordes del TImage. Sumando logro eso?

Neftali [Germán.Estévez] 27-02-2020 14:40:49

Cita:

Empezado por compuin (Mensaje 535968)
Necesito hacer el círculo más pequeño y que no toque los bordes del TImage. Sumando logro eso?


Cita:

Empezado por Neftali [Germán.Estévez] (Mensaje 535967)
...debes sumarselo a las 2 primeras Coordenadas (x1, y1) y restárselo a las 2 segundas (x2, y2).


La misma cantidad.
Sumar a las 2 primeras, restar a las 2 segundas.

compuin 27-02-2020 14:48:08

Cita:

Empezado por Neftali [Germán.Estévez] (Mensaje 535972)
La misma cantidad.
Sumar a las 2 primeras, restar a las 2 segundas.


Donde consigo esas coordenadas (x1,x2 y y1,y2) ?

ecfisa 27-02-2020 17:09:01

Hola.
Cita:

Empezado por compuin (Mensaje 535973)
Donde consigo esas coordenadas (x1,x2 y y1,y2) ?

Cita:

Empezado por ecfisa (Mensaje 535942)
Código Delphi [-]
procedure CenterEllipse(Img: TImage; x1,y1,x2,y2: Integer; aColor: TColor);
var
  C,R: TPoint;
begin
  C.X := (Img.Picture.Width) div 2;
  C.Y := (Img.Picture.Height) div 2;
  R.X := (x2-x1) div 2 ;
  R.Y := (y2-y1) div 2;
  Img.Canvas.Pen.Color := aColor;
  Img.Canvas.Ellipse(C.X - R.X,  C.Y - R.Y, C.X + R.X, C.Y + R.Y);
end;

Saludos :)

compuin 27-02-2020 17:10:36

Hola

Pero estoy usando este codigo que es el que me ha funcionado mejor a mi necesidad

Código Delphi [-]
    FormMain.Wheel.Top := 10;
    FormMain.Wheel.left:= 250;
    FormMain.Wheel.Height:= 700;
    FormMain.Wheel.Width:= 1000;

 //   Ellipse(FormMain.Wheel.Canvas.Handle, 17, 17, 674, 674);

    Windows.Ellipse(FormMain.Wheel.Canvas.Handle,
                    Max((FormMain.Wheel.Width - FormMain.Wheel.Height) div 2, 0),
                    Max((FormMain.Wheel.Height - FormMain.Wheel.Width) div 2, 0),
                    -Max((FormMain.Wheel.Width - FormMain.Wheel.Height) div 2, 0) + FormMain.Wheel.Width,
                    -Max((FormMain.Wheel.Height - FormMain.Wheel.Width) div 2, 0) + FormMain.Wheel.Height);

Como lo ajusto aqui ?

ecfisa 27-02-2020 17:37:53

Hola.
Cita:

Empezado por compuin (Mensaje 535980)
Hola

Pero estoy usando este codigo que es el que me ha funcionado mejor a mi necesidad

Código Delphi [-]
 //   Ellipse(FormMain.Wheel.Canvas.Handle, 17, 17, 674, 674);  // <===== !!!!

Como lo ajusto aqui ?

Te marqué en ese código la línea donde encuentras x1, y1, x2 e y2 (son los valores que se reciben en los parámetros de la función Ellipse)


Saludos :)

compuin 27-02-2020 17:42:10

Ahora me confundi

Esta linea genera un circulo que no esta centrado

La segunda parte del codigo genera el circulo centrado pero tocando los bordes de; TImage

Necesito un circulo centrado mas pequeno, y eso no lo hace la linea que me indicas

ecfisa 27-02-2020 18:20:39

Hola.

A ver, modifico un poco un ejemplo a ver si podes lograr lo que estas buscando.
Código Delphi [-]
...
implementation 

procedure CenterEllipse(Img: TImage; x1,y1,x2,y2: Integer; aColor: TColor);
var
  C,R: TPoint;
begin
  C.X := (Img.Picture.Width) div 2;
  C.Y := (Img.Picture.Height) div 2;
  R.X := (x2-x1) div 2 ;
  R.Y := (y2-y1) div 2;
  if (C.X-R.X < 0) or (C.Y-R.Y < 0) or
     (C.X+R.X > Img.Picture.Width) or (C.Y+R.Y >Img.Picture.Height) then
    raise Exception.Create('Elipse fuera de rango');
  Img.Canvas.Brush.Style := bsClear;
  Img.Canvas.Pen.Color := aColor;
  Img.Canvas.Ellipse(C.X - R.X,  C.Y - R.Y, C.X + R.X, C.Y + R.Y);
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  // Cargar imagen en blanco
  Image1.Picture.LoadFromFile('Blank.bmp');
  // Ajustar el ancho y el alto del TImage a la imágen
  Image1.Width  := Image1.Picture.Width;
  Image1.Height := Image1.Picture.Height;
  // color verde
  Self.Color  := clMoneyGreen;
end;


procedure TForm1.Button1Click(Sender: TObject);
var
  i,x : Integer;
begin
  x := 10;
  for i := 0 to 50 do
  begin
    CenterEllipse(Image1, x, x, x*2, x*2, clBlack);
    Inc(x, 10);
  end;
end;

Este es el resultado, todos centrados.


Saludos :)

Nota: Delphi 7 soporta raise Exception (raise command)

compuin 27-02-2020 18:47:27

Lo probare y te dejare saber

Muchas gracias


La franja horaria es GMT +2. Ahora son las 12:48:19.

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