Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   OOP (https://www.clubdelphi.com/foros/forumdisplay.php?f=5)
-   -   Array of TImage (https://www.clubdelphi.com/foros/showthread.php?t=96060)

Wellnic 16-01-2023 17:57:49

Array of TImage
 
Hola, qué hay?

En el momento de eliminar completamente las imágenes de un Array of TImage (dinámico) insertadas en un ScrollBox, ¿es suficiente con eliminar dicho ScrollBox o es conveniente eliminar cada imagen individualmente (For i:= High(fotos) DownTo Low(fotos) Do fotos[i].Free)?

Es que he hecho las dos versiones y no sé con cual quedarme :)

duilioisola 16-01-2023 18:39:32

Al liberar un array normal no se liberan las cosas a las que apunta... por lo tanto entiendo que deberías liberar cada imagen.
Para comprobarlo puedes hacer un bucle que carge y elimine el ScrollBox sin la parte de la liberación de memoria de los TImage asociados y vas mirando cuanta memoria consume windows. Si sube, ya sabes la respuesta.

Wellnic 16-01-2023 19:05:22

Lo malo es que un ordenador con 16 GB de RAM ni se iba a enterar :D... y encima las imágenes cargadas son en realidad miniaturas :) no se nota aunque cargues cientos... y en este caso es significativamente lento eliminarlas una a una.

Casimiro Notevi 16-01-2023 19:27:19

En teoría no se libera la memoria de las imágenes, ya que estas han sido creadas antes, y asignada después al scrollbox.
Yo las eliminaría, no puede ser lento como dices, debe ser algo instantáneo.

Y lo de que tiene 16 Gb no puede ser ninguna excusa :confused:

Wellnic 16-01-2023 20:48:26

Lento sí que es, tarda sus buenos cinco segundos en deshacerse de unos pocos cientos de miniaturas... claro que solo va a un tercio de la velocidad del microprocesador, lógicamente... En cuanto pueda, hago las pruebas que me sugiere Duilioisola en una máquina virtual...

duilioisola 16-01-2023 20:56:30

También puedes cargar imágenes grandes en formato BMP a todo color.
Con el Paint crea un cuadrado blanco de 1000x1000 y guárdalo en formato BMP de 24 bits.
La imagen pesará 2.86MB.
En la carga de miniaturas fuérzalo a cargar esta imagen.

Casimiro Notevi 17-01-2023 10:09:36

Cita:

Empezado por Wellnic (Mensaje 550063)
Lento sí que es, tarda sus buenos cinco segundos en deshacerse de unos pocos cientos de miniaturas... claro que solo va a un tercio de la velocidad del microprocesador, lógicamente... En cuanto pueda, hago las pruebas que me sugiere Duilioisola en una máquina virtual...

Tendríamos que ver tu código, liberar miles de imágenes debe ser casi instantáneo.
¿Por qué tienes que hacer las pruebas en una máquina virtual? :confused:

movorack 17-01-2023 14:48:44

¡Hola, Wellnic!

Como alternativa al Array, puedes hacer uso de la clase TOBjectList<T>

Cita:

Empezado por Embarcadero
TObjectList es un TList con la capacidad de liberar automáticamente entradas de objetos cuando se eliminan de la lista...

Para prueba usé un archivo de 91 Kb, la carga de las imágenes fue de 1.4 segundos y al liberarlas tomó 23 milisegundos

Código Delphi [-]
uses
  System.Generics.Collections;
const
  C_TOTAL = 1000;
var
  i, idx: integer;
  List: TObjectList< TImage >;
begin
  { Crea la lista }
  { La propiedad OwnsObjects está establecida como true por defecto -- La lista liberará los objetos automáticamente. }
  List := TObjectList< TImage >.Create();

  { Se agregan los objetos. }
  for i := 0 to C_TOTAL - 1 do
  begin
    idx := List.Add(TImage.Create(nil));
    List[idx].Picture.LoadFromFile('Image1.bmp')
  end;

  { Se libera un índice en particular } 
  List.Delete(0);

  { Se libera la lista completa } 
  List.Clear;

  { Destruir completamente la lista -- Si no se han liberado objetos de la lista, se liberan en este momento. }
  List.Free;
end.

Wellnic 17-01-2023 19:00:55

Cita:

Empezado por Casimiro Notevi (Mensaje 550065)
Tendríamos que ver tu código, liberar miles de imágenes debe ser casi instantáneo.
¿Por qué tienes que hacer las pruebas en una máquina virtual? :confused:

A qué código te refieres? El de liberar imágenes lo puse al principio, no puede ser más simple:
Código Delphi [-]
  For i:= High(fotos) DownTo Low(fotos) Do
    Begin
    fotos[i].Free;
    IDs[i].Free;
    End;

Y las creo así:
Código Delphi [-]
SetLength(fotos, mp+ 1);
fotos[mp]:= TImage.Create(ScrollBox1);
fotos[mp].SetBounds(5, (mp* 174)+ 5, 264, 168);
fotos[mp].Parent:= SrollBox1;
...
...

    SetLength(IDs, mp+ 1);
    IDs[mp]:= TEdit.Create(SrollBox1);
    IDs[mp].SetBounds(274, mosaicos[mp].Top+ 70, 1030, 46);
    IDs[mp].parent:= SrollBox1;
...
...
Nada del otro jueves :D
Como ves, además de las fotos, creo TEdit asociados, que muestran un ID para cada foto. ¿Serán los que ralentizan el borrado? (Lo curioso es que, cuando se crean muchos de esos elementos, los Tedit centrales y finales no suelen aparecer...)

Si quieres pongo el procedimiento completo, pero no creo que te fuera a aclarar mucho más...

Wellnic 17-01-2023 19:17:46

Cita:

Empezado por movorack (Mensaje 550067)
¡Hola, Wellnic!

Como alternativa al Array, puedes hacer uso de la clase TOBjectList<T>



Para prueba usé un archivo de 91 Kb, la carga de las imágenes fue de 1.4 segundos y al liberarlas tomó 23 milisegundos

Código Delphi [-]
uses
  System.Generics.Collections;
const
  C_TOTAL = 1000;
var
  i, idx: integer;
  List: TObjectList< TImage >;
begin
  { Crea la lista }
  { La propiedad OwnsObjects está establecida como true por defecto -- La lista liberará los objetos automáticamente. }
  List := TObjectList< TImage >.Create();

  { Se agregan los objetos. }
  for i := 0 to C_TOTAL - 1 do
  begin
    idx := List.Add(TImage.Create(nil));
    List[idx].Picture.LoadFromFile('Image1.bmp')
  end;

  { Se libera un índice en particular } 
  List.Delete(0);

  { Se libera la lista completa } 
  List.Clear;

  { Destruir completamente la lista -- Si no se han liberado objetos de la lista, se liberan en este momento. }
  List.Free;
end.

Le echaré un ojo, gracias...

Neftali [Germán.Estévez] 18-01-2023 12:20:12

Cita:

Empezado por Wellnic (Mensaje 550063)
Lento sí que es, tarda sus buenos cinco segundos en deshacerse de unos pocos cientos de miniaturas... claro que solo va a un tercio de la velocidad del microprocesador, lógicamente... En cuanto pueda, hago las pruebas que me sugiere Duilioisola en una máquina virtual...

Es raro, porque tal y como han comentado, para miniaturas debería ser un proceso rápido.
Otra opción podría ser crear un thread sencillo que realizara la liberación y así el programa podría continuar (habría que ver en qué momento se libera).

Wellnic 18-01-2023 20:56:11

Sí... se ve como la barra de desplazamiento vertical se va moviendo y distendiendo en orden inverso, hasta que todas las imágenes desaparecen. Así que se me ocurrió ocultar el ScrollBox y mostrar la interfaz principal (un Memo :D) antes del proceso de borrado y (al parecer) asunto arreglado ^\||/:)

Neftali [Germán.Estévez] 19-01-2023 09:46:36

En esos casos se puede mirar si se puede "desactivar" el refresco visual. Dependiendo de los componentes poseen un EnebleControls/Disablecontrols o BeginUpdate/EndUpdate o algo similar. Porque seguramente la mayor parte del tiempo se está "gastando" en el refresco de la parte visual, no en la propia destrucción de las imágenes.


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

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