Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Gráficos (https://www.clubdelphi.com/foros/forumdisplay.php?f=8)
-   -   Construir imagen a partir de valores numéricos (https://www.clubdelphi.com/foros/showthread.php?t=96327)

gusspagano 05-08-2023 21:28:38

Construir imagen a partir de valores numéricos
 
Antes que nada, muchas gracias por su ayuda.

Tengo un archivo *.txt cuyo contenido son 3 columnas y muchas filas.

columna 1 = coordenada X
columna 2 = coordenada Y
columna 3 = dato cuyo valor deseo representar

Necesito utilizar esta información para construir una imagen. las coordenadas de X y Y serían utilizadas para dar ubicación al dato de la columna 3.
La cantidad de posibles valores de los datos de la comlumna 3 no supera los 200.
Finalmente, necesito colocar esta imagen en un formulario, donde sea posible acercarla, alejarla, moverla.

Nuevamente agradezco el tiempo que se toman en ayudar.

Casimiro Notevi 06-08-2023 21:20:24

Hace 10 años preguntaste algo similar :D
Pregunta cualquier aclaración que requieras o duda que tengas.

gusspagano 07-08-2023 14:35:27

Lo siento, no recordaba que habia preguntado antes lo mismo. En su momento terminé trabajando con sistemas de información geográfica.

Las respuestas que hace años me dieron me ayudan bastante. Sin embargo, ¿existe algún componente que pueda utilizar para el mismo fin? Tal vez exista algo nuevo

Casimiro Notevi 07-08-2023 19:26:13

Es que no queda muy claro lo que quieres, yo entiendo que es un simple gráfico:



pgranados 07-08-2023 21:20:15

Yo tampoco entendí bien que es lo que buscas hacer. :confused:

Copie y pegue tu pregunta en ChatGPT y me dio escribió un código. No se si sea lo que busques

Código Delphi [-]
unit MainFormUnit;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes,
  Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.ExtCtrls, Vcl.StdCtrls, System.Generics.Collections;

type
  TCoordinate = record
    X, Y: Integer;
    DataValue: Integer;
  end;

  TMainForm = class(TForm)
    Image1: TImage;
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure Image1MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
    procedure Image1MouseWheel(Sender: TObject; Shift: TShiftState; WheelDelta: Integer; MousePos: TPoint; var Handled: Boolean);
  private
    CoordinatesList: TList;
    MaxDataValue: Integer;
    MinDataValue: Integer;
    procedure LoadDataFromFile(const FileName: string);
    procedure DrawImage;
    procedure CenterImage;
  public
    { Public declarations }
  end;

var
  MainForm: TMainForm;

implementation

{$R *.dfm}

procedure TMainForm.FormCreate(Sender: TObject);
begin
  CoordinatesList := TList.Create;
  LoadDataFromFile('ruta_del_archivo.txt');
  DrawImage;
  CenterImage;
end;

procedure TMainForm.FormDestroy(Sender: TObject);
begin
  CoordinatesList.Free;
end;

procedure TMainForm.LoadDataFromFile(const FileName: string);
var
  FileStream: TStreamReader;
  X, Y, DataValue: Integer;
  Coordinate: TCoordinate;
begin
  if not FileExists(FileName) then
    raise Exception.Create('El archivo no existe.');

  FileStream := TStreamReader.Create(FileName);
  try
    while not FileStream.EndOfStream do
    begin
      FileStream.ReadLine;
      if TryStrToInt(FileStream.ReadLine, X) and
         TryStrToInt(FileStream.ReadLine, Y) and
         TryStrToInt(FileStream.ReadLine, DataValue) then
      begin
        Coordinate.X := X;
        Coordinate.Y := Y;
        Coordinate.DataValue := DataValue;
        CoordinatesList.Add(Coordinate);

        // Actualizar los valores máximos y mínimos para escalar correctamente la imagen
        if DataValue > MaxDataValue then
          MaxDataValue := DataValue;
        if DataValue < MinDataValue then
          MinDataValue := DataValue;
      end;
    end;
  finally
    FileStream.Free;
  end;
end;

procedure TMainForm.DrawImage;
var
  I: Integer;
  DataRange: Integer;
begin
  Image1.Picture.Bitmap.SetSize(Image1.Width, Image1.Height);
  DataRange := MaxDataValue - MinDataValue;
  for I := 0 to CoordinatesList.Count - 1 do
  begin
    with CoordinatesList[i] do
    begin
      // Escalar el valor del dato al rango 0-255 para asignar el color en la imagen
      Image1.Picture.Bitmap.Canvas.Pixels[X, Y] := RGB(0, Trunc(255 * (DataValue - MinDataValue) / DataRange), 0);
    end;
  end;
end;

procedure TMainForm.CenterImage;
var
  ImageRect, ClientRect: TRect;
begin
  ImageRect := Image1.BoundsRect;
  ClientRect := ClientRect;
  OffsetRect(ImageRect, (ClientRect.Width - ImageRect.Width) div 2, (ClientRect.Height - ImageRect.Height) div 2);
  Image1.BoundsRect := ImageRect;
end;

procedure TMainForm.Image1MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
  if Button = mbLeft then
    Image1.BeginDrag(True);
end;

procedure TMainForm.Image1MouseWheel(Sender: TObject; Shift: TShiftState; WheelDelta: Integer; MousePos: TPoint;
  var Handled: Boolean);
begin
  // Acercar o alejar la imagen según la dirección del scroll
  if WheelDelta > 0 then
    Image1.Width := Image1.Width + 10
  else
    Image1.Width := Image1.Width - 10;

  Image1.Height := Image1.Width;
  CenterImage;
  Handled := True;
end;

end.

mamcx 07-08-2023 21:25:18

Cita:

Empezado por gusspagano (Mensaje 552263)
información para construir una imagen. las coordenadas de X y Y serían utilizadas para dar ubicación al dato de la columna 3.

Faltan muchos datos! Que tipo de imagen, que formatos, que es "ubicación", etc!

gusspagano 08-08-2023 18:37:16

Cita:

Empezado por pgranados (Mensaje 552277)
Yo tampoco entendí bien que es lo que buscas hacer. :confused:

Copie y pegue tu pregunta en ChatGPT y me dio escribió un código. No se si sea lo que busques

Código Delphi [-]
...

Creo que esto es lo que necesito, voy a intentarlo. ¡Te agradezco mucho!

gusspagano 08-08-2023 18:57:43

Una disculpa por la poca claridad. Sólo uso la programación ocasionalmente, y para asuntos sumamente básicos.

Supongamos que tengo una imagen con todos los pixeles en color blanco. Esta imagen tiene 100 columnas y 100 renglones.

Por otra parte tengo un archivo txt con tres columnas y 10,000 filas (100 columnas x 100 renglones = 10,000).

La primera columna del txt me indica a su vez una columna de la imagen, la segunda columna del txt me indica la fila de la imagen, la tercer columna del txt me indica un dato cuyo valor voy a utilizar para asignarle un color al correspondiente pixel de la imagen.

Por ejemplo, si la primera línea del txt fuera: 1 1 20. Significa que al pixel correspondiente a la columna 1, de la fila 1, le voy a dar un color que corresponde al valor 20.

Ahora, no sé cómo crear dicha "imagen" para empezar, y tampoco sé cómo pasarle valores. El código de ChatGPT que amablemente nos proporciona pgranados ayuda bastante.

MAXIUM 08-08-2023 21:18:25

Usando PutPixel

Image.Canvas.Pixels[Pto.X, Pto.Y] := Color;

Aunque tampoco sé que clase de imagen quieres dibujar. Si lineas entre puntos o solo los puntos.

gusspagano 09-08-2023 00:23:25

Cita:

Empezado por MAXIUM (Mensaje 552283)
Usando PutPixel

Image.Canvas.Pixels[Pto.X, Pto.Y] := Color;

Aunque tampoco sé que clase de imagen quieres dibujar. Si lineas entre puntos o solo los puntos.

Gracias por el aporte MAXIUM!

Intengo dibujar una imagen de precipitación estimada por radar, no hay puntos lineas y polígonos, solo pixeles de colores cuyo color indica la intensidad de lluvia en el momento del escaneo de la atmosfera.

Puede ser por ejemplo que la mayor intensidad de lluvia se represente con rojo intenso y la menor intensidad con verde suave. Los pixeles cuyas ubicaciones registren intensidades de cero o por inferiores de cierto umbral pueden ser transparentes o sin color.

MAXIUM 09-08-2023 05:23:39

Cita:

Empezado por gusspagano (Mensaje 552284)
Gracias por el aporte MAXIUM!

Intengo dibujar una imagen de precipitación estimada por radar, no hay puntos lineas y polígonos, solo pixeles de colores cuyo color indica la intensidad de lluvia en el momento del escaneo de la atmosfera.

Puede ser por ejemplo que la mayor intensidad de lluvia se represente con rojo intenso y la menor intensidad con verde suave. Los pixeles cuyas ubicaciones registren intensidades de cero o por inferiores de cierto umbral pueden ser transparentes o sin color.

Bueno, te dejo la primera parte que lee el txt y dibuja. Por supuesto hay formas más elegantes para cada proceso, pero mi idea es que sea facil de entender.

Le faltan cosas como escoger una mejor paleta de colores, poder limpiar y volver a dibujar, escalar, exportar la imagen, etc. Espero te sirva y me queda la duda si te pidieron usar Delphi u otro lenguaje, no porque no se pueda sino por curiosidad.

Archivo TXT de prueba
Código:

1 1 20
10 20 32
12 23 54
40 56 72
45 78 62
62 38 60

Código fuente
Código Delphi [-]
procedure TForm1.Button1Click(Sender: TObject);
Var
   ArchivoTXT: TStringList;
   Desde, X, Y, Color: Integer;
   Valores: TArray<string>;
   Linea: String;
begin
  // Estructura para manejar archivos.
     ArchivoTXT:= TStringList.Create;

  // Abre un cuadro de dialogo para cargar un archivo en la estructura ArchivoTXT.
     If OpenDialog1.Execute Then
        ArchivoTXT.LoadFromFile(OpenDialog1.FileName);

  // Ciclo que va leyendo linea a linea el archivo cargado.
     For Desde:= 0 To (ArchivoTXT.Count -1) Do
     Begin
          Linea:= ArchivoTXT.Strings[Desde];
          Valores:= Linea.Split([' ']);      // Extrae los valores de la linea (sepadaos por espacio)-
          X    := StrToInt(Valores[0]);      // El primer valor lo convierte a número y lo usa para la posición X
          Y    := StrToInt(Valores[1]);      // El segundo valor lo convierte a número y lo usa para la posición Y
          Color:= StrToInt(Valores[2]);      // El tercer valor lo convierte a número y lo usa para el color.

       // Dibuja un pixel en la posición y color.
          Image1.Canvas.Pixels[X, Y]:= Color;
     End;

  // Libera la estructura.
     ArchivoTXT.Free
end;

procedure TForm1.FormShow(Sender: TObject);
begin
  // Dibuja un rectangulo para resaltar el área de dibujo.
     Image1.Canvas.Rectangle(0, 0, 101, 101);
end;

Componentes usado


Datos cargados


Zoom de los datos cargados

gusspagano 07-09-2023 18:16:57

Finalmente se pudo.

Gracias a todos por ayuda. Saludos!

Casimiro Notevi 07-09-2023 18:52:08

^\||/^\||/^\||/


La franja horaria es GMT +2. Ahora son las 00:52:16.

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