Ir al contenido



Foto

dibujar polígono sobre imagen Stretch


  • Por favor identifícate para responder
9 respuestas en este tema

#1 el-mono

el-mono

    Advanced Member

  • Miembros
  • PipPipPip
  • 132 mensajes

Escrito 08 marzo 2016 - 06:54

Buenas.Necesito imperiosamente hacer estos pasos:
 
(Uso Delphi 10 Seatle)
 
1) Sobre un control Timage cargo una imagen con propiedad WapMode en Original y luego sobre el canvas de la imagen dibujo una forma "poligono " con coordenadas que ya tengo establecidas en el código y que me dibuja el polígono en la zona de la imagen que deseo.
 
2) Luego sobre otro Timage cargo nuevamente la misma imagen pero con propiedad WrapMode a Stretch y el polígono se dibuja en cualquier otro lado con las coordenadas que tenia.
 
Pregunta: Como hago para calcular las nuevas coordenadas para dibujar el polígono sobre la misma ubicación de la imagen con propiedad Stretch ?

  • 0

#2 Delphius

Delphius

    Advanced Member

  • Administrador
  • 6.286 mensajes
  • LocationArgentina

Escrito 08 marzo 2016 - 07:32

Ummm. No entiendo.

Si realmente quieres que el polígono que dibujas sobre el TImage respete el mismo Stretch que aplica el TImage a la imagen original entonces me parece a mi que lo más apropiado es que guardes una copia de la imagen con dicho polígono del paso paso 1.

Y luego en el 2do TImage con Stretch cargas dicha copia.

 

Me parece que es lo más adecuado y fácil. Sin saber como es el algoritmo que aplica el TImage al momento de estrechar la imagen lo vas a tener difícil saber cual sería la nueva coordenada de la posición de los vértices.

 

Si nos das más detalles de lo que estás haciendo, y una muestra de prueba de concepto para hacernos una idea podríamos ver algunas opciones y/o alternativas.

 

Saludos,


  • 0

#3 genriquez

genriquez

    Advanced Member

  • Miembro Platino
  • PipPipPip
  • 528 mensajes
  • LocationCali, Colombia

Escrito 08 marzo 2016 - 07:42

Lo más fácil debería ser aplicar el polígono sobre la imagen antes de asignarla al timage, así el strech se aplica tanto a la imagen como al polígono, de lo contrario tendrías que descifrar el algoritmo que utiliza el timage para hacer el strech y aplicarlo a las coordenadas del polígono y así con las coordenadas transformadas te quedará bien el polígono.

 

Alguna vez intenté hacer algo parecido, pero no lo terminé por falta de tiempo, si lo haces, porfa retroalimentanos.

el código decía algo así.


php
  1. HScale := FRawBitmap.Width / MainImage.Width;
  2. VScale := FRawBitmap.Height / MainImage.Height;
  3.  
  4. If HScale > VScale then
  5. Factor := HScale
  6. Else
  7. Factor := VScale;
  8.  
  9.  
  10. R1.Left := (Selection2.Position.X - FImageRect.Left) * Factor;
  11. R1.Top := (Selection2.Position.Y - FImageRect.Top) * Factor;
  12. R1.Width := (Selection2.Width) * Factor;
  13. R1.Height := (Selection2.Height) * Factor;


  • 0

#4 el-mono

el-mono

    Advanced Member

  • Miembros
  • PipPipPip
  • 132 mensajes

Escrito 08 marzo 2016 - 08:16

Gracias por responder.

 

Lo que hago es dibujar un polígono mediante PathData usando Firemonkey con relleno transparente luego haciendo clic sobre el path dibujado y mediante la función PtInRect puedo repintar el polígono del path cliqueado con un color y borde. Esto me funciona si la imagen esta en modo Original si yo pongo la imagen a Stretch la función PtInRect no me reconoce las coordenadas aunque le haga click sobre la misma zona de la imagen por ello es que quería calcular las nuevas coordenadas y pesarle a la función para saber si las coordenadas están o no dentro del Path donde se hizo click.


  • 0

#5 Delphius

Delphius

    Advanced Member

  • Administrador
  • 6.286 mensajes
  • LocationArgentina

Escrito 08 marzo 2016 - 08:38

 

Lo más fácil debería ser aplicar el polígono sobre la imagen antes de asignarla al timage, así el strech se aplica tanto a la imagen como al polígono, de lo contrario tendrías que descifrar el algoritmo que utiliza el timage para hacer el strech y aplicarlo a las coordenadas del polígono y así con las coordenadas transformadas te quedará bien el polígono.

 

Alguna vez intenté hacer algo parecido, pero no lo terminé por falta de tiempo, si lo haces, porfa retroalimentanos.

el código decía algo así.


php
  1. HScale := FRawBitmap.Width / MainImage.Width;
  2. VScale := FRawBitmap.Height / MainImage.Height;
  3.  
  4. If HScale > VScale then
  5. Factor := HScale
  6. Else
  7. Factor := VScale;
  8.  
  9.  
  10. R1.Left := (Selection2.Position.X - FImageRect.Left) * Factor;
  11. R1.Top := (Selection2.Position.Y - FImageRect.Top) * Factor;
  12. R1.Width := (Selection2.Width) * Factor;
  13. R1.Height := (Selection2.Height) * Factor;

 

Recuerdo haber visto alguna vez un código similar a esto en Delphi. No se si en la VCL o si era algún truco compartido en el foro. En Lazarus parece que las cosas son un tanto diferentes y hasta ahora no le encuentro algo parecido o el código que aplica justamente el estrechamiento. Es un mar de llamadas a procedimientos hasta lo más profundo de la rama de herencias y no veo en ninguno de ellos código concreto.

 

Saludos,


  • 0

#6 cram

cram

    Advanced Member

  • Miembro Platino
  • PipPipPip
  • 824 mensajes
  • LocationMisiones, Argentina

Escrito 09 marzo 2016 - 06:38

Según entiendo lo que deseas es comparar un polígono en una imagen con y sin Stretch.

Se me ocurre que calcules las proporciones usando el tamaño de la imagen contra el tamaño del contenedor (control).

Las coordenadas le pasarás mediante código, por lo que no habría mayores problemas.

 

Saludos


  • 0

#7 el-mono

el-mono

    Advanced Member

  • Miembros
  • PipPipPip
  • 132 mensajes

Escrito 09 marzo 2016 - 07:57

es lo que creo necesito pero no se como hacerlo.


  • 0

#8 Delphius

Delphius

    Advanced Member

  • Administrador
  • 6.286 mensajes
  • LocationArgentina

Escrito 09 marzo 2016 - 09:19

Según entiendo lo que deseas es comparar un polígono en una imagen con y sin Stretch.

Se me ocurre que calcules las proporciones usando el tamaño de la imagen contra el tamaño del contenedor (control).

Las coordenadas le pasarás mediante código, por lo que no habría mayores problemas.

 

Saludos

 

Mucho me temo que no es tan simple como calcular el factor de proporción y hacer regla de 3 simple para encontrar la coordenada en la imagen con Stretch.

Lo de esperarse es que cuando uno aplica Stretch es que no sólo se reduce la imagen a cierto tamaño, sino que además internamente para distribuir los pixeles debe aplicar un algoritmo de interpolación o de filtrado para predecir que pixel y color corresponde. Imagina al Strech como una especie de zoom negativo, es decir, que en lugar de agrandar o acercarnos, tenemos que achicar o alejarnos.

 

De lo que recuerdo de mis tiempos sobre estudio de tratamiento de imagen y mutimedia. Una de las técnicas más básica de "zoom" consiste en tomar dos pixeles A y B y aplicar interpolación lineal para predecir un valor intermedio.

Por ejemplo si la imagen original es 2x2 = {AB, CD} y se quisiera aplicar un zoom x1,5 se consigue esto: 3x3 = {AeB, xyz, CfD} siendo e = Promedio(A,B), x = Promedio(A,C) y así para el resto.

Para un zoom de x2 será de 4x4 y ahora hay que estimar dos puntos intermedios para las duplas (A,B), (A,C), (B,D), (C,D). Y así para valores mayores.

 

Imagina ahora que queremos hacer el paso inverso... tenemos algo de una dimensión mayor y queremos ir a una menor... Necesariamente se debe aplicar un algoritmo que tome un grupo de pixeles vecinos y con ellos haga alguna estimación y prediga el nuevo pixel a tomar.

 

Si le sumas ahora que en realidad el estrechamiento puede no ser proporcional en ambos ejes... peor se pone.

 

Como vez, no existe necesariamente una correlación directa entre una coordenada en una imagen real y una estrechada. Lo digo en parte por experiencia de mi trabajo en la oficina de mi viejo. Ellos en el estudio de agrimensura trabajan con imágenes digitales y necesitan mantener siempre en proporción las medidas. Una vez mi hermano tomo una foto satelital, al llevarla a autocad por error la estrechó y luego al medir en el lugar las medidas obviamente diferían y no había escala.

 

Insisto: si se desea "mantener" el polígono "en proporción" en la imagen estrechada no queda otra que guardar una copia de la original con dicho polígono y luego a ésta copia pasar al TImage estrechado para ver como sale.

 

Saludos,


  • 0

#9 cram

cram

    Advanced Member

  • Miembro Platino
  • PipPipPip
  • 824 mensajes
  • LocationMisiones, Argentina

Escrito 09 marzo 2016 - 02:32

es lo que creo necesito pero no se como hacerlo.

 

¿Dibujar en el canvas de la imagen o mantener la proporción?

 

Para mantener la proporción basta con conseguir una tasa de proporción, ejemplo: T = A/B. Ese valor te dará un factor para poder multiplicar el tamaño del polígono en la nueva imagen.

No te puedo pasar un código para escribir sobre una imagen, pero básicamente se trata de tomar el canvas que contiene al bitmap. Es en el canvas en el que realizarás las operaciones de trazado usando pen, brush, etc.

 

Según lo que dice Delphius los cálculos se salen de las posibilidades de lograr algo, pero supongo que lo que deseas es un producto visual y no un cálculo exacto, por lo que aplicando un simple factor al polígono bastará.

 

El bitmap contiene sus dimensiones: alto y ancho, mientras que el control visual (contenedor) también tiene sus propias dimensiones: alto y ancho.

La imagen ajustada a las dimensiones del control poseerán precisamente, las dimensiones del control, mientras que las dimensiones de la imagen no ajustada (original) tendrán la otra dimensión.

 

P:= Altura_Bitmap_Original / Altura_Control

 

Para dibujar el polígono en el bitmap ajustado, deberás multiplicarlo por la proporción P. Sea más chica o más grande, el factor hará su trabajo igual.

 

Ahora, hay que tener en cuenta que al ajustar, puede ser que las proporciones alto/ancho de la imagen original cambien con las proporciones alto/annho del control, si es así, es decir, si el ajuste no es proporcional a sus medidas originales, deberás hacer uso de dos proporciones, una para el alto y otra para el ancho.

 

Saludos


  • 0

#10 el-mono

el-mono

    Advanced Member

  • Miembros
  • PipPipPip
  • 132 mensajes

Escrito 09 marzo 2016 - 04:10

Muchísimas gracias Cram, Genriquez y Delphius. Tenias razón Cram mi necesidad era meramente visual no necesariamente cálculos exactos.Lo que me sirvio a mi es el siguiente codigo por si le sirve a alguien mas:


delphi
  1. ancho := image1.Bitmap.Canvas.Width / image1.Width;
  2. alto := image1.Bitmap.Canvas.Height / image1.Height;
  3.  
  4. x := x * ancho;
  5. y := y * alto;
  6. if image1.Canvas.PtInPath(pointf(x,y),path16a) then
  7. begin
  8.  
  9. image1.Bitmap.Canvas.BeginScene;
  10. image1.Bitmap.Canvas.Fill.Kind := Tbrushkind.Solid;
  11. image1.Bitmap.Canvas.Fill.Color := Talphacolorrec.blue;
  12. image1.Bitmap.Canvas.FillPath(path16a,0.5);
  13. image1.Bitmap.Canvas.EndScene;
  14. end;


  • 1