Ver Mensaje Individual
  #38  
Antiguo 03-05-2013
Avatar de radenf
radenf radenf is offline
Miembro
 
Registrado: oct 2007
Ubicación: Viña del Mar,Chile
Posts: 608
Reputación: 19
radenf Va por buen camino
Solucionado

Después de muchos intentos y pruebas fallidas descubrí que la CnsDMTable carga las imágenes usando threads sobre un MemoryStream, mediante los parámetros AKeepStream y ALoadFrameinThread, es decir el componente, según entiendo viene desarrollado para cargar las imágenes a la máxima velocidad que permita el PC.
Utilizando el siguiente código logré acelerar la carga de las imágenes a escasos segundos en series grandes de más de 1000 imágenes:

Código Delphi [-]
procedure TVisor.ButtonCargarClick(Sender: TObject);
var
I:Integer;
c1: TCursor;
begin
c1 := Screen.Cursor;
Screen.Cursor := crHourGlass;
CnsDMTable1.Create(Self); // crea la tabla (este paso es fundamental)
ListBox1.Items.Clear;
FindFile.Threaded := False;
with FindFile.Criteria.Files do
begin
FileName := '*.dcm';
Location := (DBEditDir.Text); // Directorio donde se almacenan los archivos de imágenes, ruta guardada en la BD
Subfolders := Self.Subfolders.Checked;
end;
begin
FindFile.Execute;// Extrae la ruta de los archivos de imágenes y los muestra en un ListBox
Application.ProcessMessages;
end;
begin
for I := 0 to (ListBox1.Items.Count - 1) do
CnsDMTable1.LoadfromFile(ListBox1.Items.Strings [i]);// carga las imágenes
Application.ProcessMessages;
try
DicomMultiViewer1.DicomDatasets:= CnsDMTable1;// carga los visores
DicomMultiViewer2.DicomDatasets:= CnsDMTable1;
DicomMultiViewer3.DicomDatasets:= CnsDMTable1;
DicomMultiViewer4.DicomDatasets:= CnsDMTable1;
DicomMultiViewer5.DicomDatasets:= CnsDMTable1;
DcmMultiImage1.DicomDatasets:= CnsDMTable1;
finally
if assigned(DicomMultiViewer1.DicomDatasets) and (DicomMultiViewer1.DicomDatasets.Count > 0) then
begin
DicomMultiViewer1.ActiveView.Attributes.ImageData.MagnificationType:= mftCUBIC;// asigna propiedades
DicomMultiViewer2.ActiveView.Attributes.ImageData.MagnificationType:= mftCUBIC;
DicomMultiViewer2.LeftMouseInteract:= miZoom;
DicomMultiViewer1.LeftMouseInteract:= miZoom;
Screen.Cursor := c1;
end;
end;
end;
end;

y para llamarlo:

Código Delphi [-]
procedure TVisor.DBAdvGrid1ClickCell(Sender: TObject; ARow, ACol: Integer);
begin
if (ACol = 2) then
begin
CnsDMTable1.Clear;// esto vacía la tabla y libera la memoria
ButtonCargar.ButtonClick;
end;

y de este modo ya no tengo violaciones de acceso a memoria y el programa corre sin problemas.
FindFile es un componente que permite obtener la ruta de todos los archivos existentes en un directorio, incluidos los subdirectorios y cargarlos como strings en un ListBox. Para 1000 archivos tarda 180 msegs.
Espero que a alguien más le pueda servir.

Saludos y gracias por sus aportes
Responder Con Cita