Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Principal > Gráficos
Registrarse FAQ Miembros Calendario Guía de estilo Temas de Hoy

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 31-08-2003
cesarjbf cesarjbf is offline
Miembro
 
Registrado: may 2003
Posts: 54
Poder: 21
cesarjbf Va por buen camino
Mostrar Fotos D' 5 En 5

la pregunta es acerca de como me recomendabas mostrar 600 fotos jpg's,la idea es que se necesitan mostrar en forma de thumbnails de 5 en 5 por cada vez que se presiona un botton,un boton para mostrar las proximas 5(>>) y otro para mostrar las 5 anteriores(<<)yo decia que si era buena idea utilizar una forma por cada 5 fotos pero tendrian que ser 120 formas, no es malo para una sola aplicacion cargarla de tantas formas,hay otra manera? ........ Gracias de antemano
__________________
Mexicali

Última edición por cesarjbf fecha: 10-09-2003 a las 13:08:58.
Responder Con Cita
  #2  
Antiguo 10-09-2003
cesarjbf cesarjbf is offline
Miembro
 
Registrado: may 2003
Posts: 54
Poder: 21
cesarjbf Va por buen camino
listo,ya esta corregido el hilo ahora si puedo esperar la respuesta
__________________
Mexicali
Responder Con Cita
  #3  
Antiguo 10-09-2003
andres1569 andres1569 is offline
Miembro
 
Registrado: may 2003
Posts: 908
Poder: 22
andres1569 Va por buen camino
Hola:

Desde luego, ni se te ocurra crear 120 formularios para almacenar en cada uno 5 imágenes diferentes, a parte eso supone cargar en exceso el programa con imágenes, aunque estas sean en formato jpg.

Imagino que las imágenes se cargan desde una carpeta que tienes localizada. Voy a suponer que tienen nombres serializados, al estilo de Imagen0001, Imagen0002, ..., con ellos se simplifica la cosa porque ya sabemos de antemano los nombres de los ficheros que queremos cargar.

Supongamos también que has metido 5 componentes TImage en el formulario. Pues bien, creas una variable global NumImagen de tipo Integer, que almacena el número de la primera serie de imágenes que estás mostrando. Defines en el formulario un método CargaImagenes como el siguiente:

Código:
var
  NumImagen : Integer;

Implementation

procedure TForm1.CargaImagenes;
var
  NomArchivo : String;
begin
  NomArchivo := DirImagenes + '\Imagen';
  Image1.LoadFromFile (NomArchivo + FormatFloat ('0000', NumImagen + 1) + '.jpg');
  Image2.LoadFromFile (NomArchivo + FormatFloat ('0000', NumImagen + 2) + '.jpg');
  Image3.LoadFromFile (NomArchivo + FormatFloat ('0000', NumImagen + 3) + '.jpg');
  Image4.LoadFromFile (NomArchivo + FormatFloat ('0000', NumImagen + 4) + '.jpg');
  Image5.LoadFromFile (NomArchivo + FormatFloat ('0000', NumImagen + 5) + '.jpg');
end;

// inicializamos los TImage al cargar el formulario
procedure TForm1.Form1Create;
begin
  NumImagen := 0;
  CargaImagenes;
end;

procedire TForm1.BotonSiguientesClick (Sender: TObject);
begin
  if NumImagen = 595 then EXIT;
  Inc (NumImagen, 5);
  CargaImagenes;
end;

procedire TForm1.BotonAnterioresClick (Sender: TObject);
begin
  if NumImagen = 0 then EXIT;
  Dec (NumImagen, 5);
  CargaImagenes;
end;
Desarrollando esta idea debes conseguir lo que buscas. Si no tienes las imágenes con nombres serializados, de forma que se pueda deducir su nombre, lo ideal sería cargar en una lista (TStringList) los nombres de todos los ficheros .jpg, e ir cogiendo de ahí cada vez los nombres de los ficheros que queremos mostrar. Si tienes alguna duda sobre cómo hacer esto, vuelve a postear

Saludos
__________________
Guía de Estilo
Responder Con Cita
  #4  
Antiguo 17-09-2003
cesarjbf cesarjbf is offline
Miembro
 
Registrado: may 2003
Posts: 54
Poder: 21
cesarjbf Va por buen camino
MUCHAS GRACIAS CON ESTO MI PROBLEMA ESTA RESUELTO............
__________________
Mexicali
Responder Con Cita
  #5  
Antiguo 17-09-2003
__cadetill __cadetill is offline
Miembro
 
Registrado: may 2003
Posts: 3.387
Poder: 25
__cadetill Va por buen camino
Hola

Si no tubieran nombres serializados, lo que puedes hacer es cargar el nombre de todas las imagenes en un TStringList mediante FindFirst y FindNext y utilizar la misma idea que te ha comentado el amigo Andrés pero con el índice (apuntador) del TStringList
Responder Con Cita
  #6  
Antiguo 07-10-2003
cesarjbf cesarjbf is offline
Miembro
 
Registrado: may 2003
Posts: 54
Poder: 21
cesarjbf Va por buen camino
El problemma esta en que al momento de estar cambiando las imagenes tardan un tiempo no muy considerable en cargarse pero si uno quiere avanzar rapido hacia adelante entonces ese tiempo si es notorio, las imagenes tienen que ser menores a 12kb para no tardar tanto en cargar pero esto le resta mucha resolucion, como podria solucionarse esto? tal vez cargandolas en memoria, pero son 1000 imagenes (Las imagenes son puras caratulas de discos compactos).

Gracias de antemano..............
__________________
Mexicali
Responder Con Cita
  #7  
Antiguo 10-10-2003
andres1569 andres1569 is offline
Miembro
 
Registrado: may 2003
Posts: 908
Poder: 22
andres1569 Va por buen camino
Hola César, te voy a dar algunas ideas:

Lo normal, si el usuario va a navegar mucho por las imágenes, es que no quiera hacerlo siempre de forma secuencial; me explico, si tenemos 500 imágenes y estamos situados en el grupo 6 a la 10, y queremos ver el grupo 276-280, lo lógico es que brindemos algún mecanismo (poner algún control adecuado) para que ese salto sea inmediato, sin tener que recorrer todas las imégenes intermedias. Para ello puedes poner un TSpinEdit donde el usuario escriba el nº de foto a visualizar (o el nº de la primera foto del grupo, siguiendo el ejemplo que pones), y un botón BotonVerImagenes que ejecute esa carga. De acuerdo al código que te puse, sería algo así:

Código:
procedure TForm1.BotonVerImagenesClick (Sender: TObject);
begin
// para que coja a partir de la primera imagen del grupo de 5
// hacemos la siguiente instrucción
  NumImagen := 5 * (SpìnEdit1.Value div 5);
  if NumImagen = 600 then NumImagen := 595;  // chapucilla casera
  CargaImagenes;
end;
Acuérdate de fijar en el SpinEdit la propiedad MaxValue al total de imágenes disponibles (600 en tu caso)

Si aún así ves que algo va lento, o que el usuario sigue empecinado en recorrer las imágenes con los botones Anterior y Siguiente, deberías plantearte un poco más de programación, creando 5 objetos TPicture en el formulario e ir cargándolos uno tras otro mediante su método LoadFromFile (comprobando tras cada carga que el usuario no haya pulsado de nuevo un botón de avance/retroceso). Si se han cargado las 5 imágenes en sus respectivos TPicture, se dibujan mediante el método Draw sobre un Canvas (el del formulario mismo, o sobre un TPaintBox). Si el usuario pulsa un botón mientras se están cargando las imágenes, entonces no se dibuja nada y se empieza a cargar el siguiente grupo. De esta forma, todo irá más ligero.

Espero haberme explicado, un saludo
__________________
Guía de Estilo
Responder Con Cita
  #8  
Antiguo 10-10-2003
Avatar de guillotmarc
guillotmarc guillotmarc is offline
Miembro
 
Registrado: may 2003
Ubicación: Huelva
Posts: 2.638
Poder: 24
guillotmarc Va por buen camino
Hola.

Además, cuando muestras en pantalla 5 imagenes, podrías ir cargando en memória las 5 siguientes y las 5 anteriores, de esta forma cuando quiera pasar a la siguiente página, será immediato.

Es decir, aprovechas el tiempo muerto en que el usuario está mirando las 5 imagenes en pantalla, para poner en memória las imagenes adyacentes.

De esta forma, el programa hará más trabajo, puesto que cargará imagenes en memoria que igual no nos van a hacer falta, pero el usuario tendrá la impresión de que es más rápido, puesto que el trabajo extra se hace en un tiempo muerto (mientras está mirando las fotos), y en cambio cuando el usuario seleccione una opción (Anterior, Siguiente) el programa responderá mucho más rápido.

Saludos.
__________________
Marc Guillot (Hi ha 10 tipus de persones, els que saben binari i els que no).
Responder Con Cita
  #9  
Antiguo 10-10-2003
Avatar de roman
roman roman is offline
Moderador
 
Registrado: may 2003
Ubicación: Ciudad de México
Posts: 20.269
Poder: 10
roman Es un diamante en brutoroman Es un diamante en brutoroman Es un diamante en bruto
Vamos a ver:

andres1569 indica un punto crucial: ver las imágenes aleatoriamente y no secuencialmente.

marcguillot sugiere optimizar la visualización cargando imágenes por adelantado.

Ambos puntos son buenos pero algo incompatibles pues si seguimos la idea de andres1569 será difícil saber cuáles imágenes serán las próximas a cargar y si seguimos la idea de marcguillot será difícil dejar el acceso secuencial.

Sin embargo, ¿por qué no dejar que Windows se encargue de cuándo cargar las imágenes y aún así permitir un acceso aleatorio?

La propuesta que hago es usar un ListView en modo virtual

Código:
OwnerData := true;
En modo virtual nosotros especificamos cuántos items hay

Código:
  ListView.Items.Count := 1000000; // ¡Incluso más si lo desean!
pero no se los damos de un sólo golpe sino que usamos el evento OnData del ListView. Este evento nos da un Item "falso" con sólo una propiedad asignada: el índice del item que debe mostrarse en ese momento. Nosotros llenamos el resto:

Código:
Item.Caption := Lista[Item.Index];
donde Lista podría ser un StringList que llenamos al principio del programa con los nombres de los archivos.

Ahora bien, ¿de dónde y cuándo sacamos la imágen de cada ítem?

Llenar un ImageList con todas las imágenes es desde luego impensable ya que justamente deseamos evitar cargar todas las imágenes al mismo tiempo.

Pero podemos usar el evento OnCustomDrawItem del ListView para cargar la imágen y dibujarla:

Código:
var
  Rect: TRect;
  Bmp: TBitmap;
  X, Y: Integer;

begin
  // Cargar la imagen
  Bmp := TBitmap.Create;
  Bmp.LoadFromFile('ruta al archivo' + Item.Caption);

  // Obtener el rectángulo que ocupa el icono del item
  ListView_GetItemRect(ListView.Handle, Item.Index, Rect, LVIR_ICON);

  // Para centrar la imagen en el área del icono
  X := Rect.Left + ((Rect.Right - Rect.Left) - Bmp.Width) div 2;
  Y := Rect.Top + ((Rect.Bottom - Rect.Top) - Bmp.Height) div 2;

  ListView.Canvas.Draw(L, T, Bmp);
  Bmp.Free;
El área de los iconos deberá ser lo suficietemente grande para que quepa la imagen. Como las imágenes son "thumbnails" supongo que serán del mismo tamaño, digamos de 160x160.

Entonces sólo hay que asignar al ListView un ImageList con sus propiedades Width y Height en 160.

El ImageList no lo llenamos, es sólo para que el área de los iconos sea adecuada.

No lo he probado a consciencia más que nada porque en estos momentos no dispongode 1000 imágenes .

Lo que hice fue usar una sóla imagen cargando la lista de nombres de archivos con el mismo nombre de manera que realmente se está cargando cada vez la imágen.

Lo probé con 100,000 items y funciona bien.

La prueba final será con las 1000 mágenes distintas pero creo que vale la pena intentarlo.

// Saludos

Última edición por roman fecha: 10-10-2003 a las 23:23:28.
Responder Con Cita
  #10  
Antiguo 11-10-2003
Avatar de guillotmarc
guillotmarc guillotmarc is offline
Miembro
 
Registrado: may 2003
Ubicación: Huelva
Posts: 2.638
Poder: 24
guillotmarc Va por buen camino
Hola.

Creo que mi propuesta y la de Andrés són compatibles. Por eso empezé con un Además porqué realmente me parece muy recomendable la proposición de Andrés.

Es absurdo obligar a pasar por todas las imagenes para ir a una imagen determinada. Por lo que es muy adecuado poner unos botones de inicio final y Ir a, (o una combo, un SpinEdit, ...).

Aunque cuando saltamos a una imagen (a un grupo de 5 imagenes en realidad), siempre podemos aprovechar, una vez mostradas las imagenes en pantalla, para ir cargando las siguientes imagenes, por si al usuario le da por ir a las anteriores o siguientes (són las imagenes con más probabilidades de ser seleccionadas por el usuario).

El tema del ListView me parece perfectamente correcto, como implementación concreta a utilizar. Puesto que además de permitir el salto a un punto determinado, propuesto por Andrés. También podemos aprovechar, una vez ha cargado la imagen el evento OnCustomDraw, para poner en memória (supongamos en unos TJpeg), las imagenes adyacentes, por si el usuario hace un movimiento secuencial, podamos utilizar esas imagenes en memória en la siguiente llamada al OnCustomDraw (disminuyendo drasticamente el tiempo que tardará en ejecutarse).

NOTA : Aunque utilizar un ListView me parece una solución correcta, tampoco no la encuentro necesaria. Puesto que 5 TPicture, y una combo o un SpinEdit (para saltar a una imagen determinada), me parecen más sencillos de implementar, e igualmente validos.

Saludos.
__________________
Marc Guillot (Hi ha 10 tipus de persones, els que saben binari i els que no).

Última edición por guillotmarc fecha: 11-10-2003 a las 00:15:25.
Responder Con Cita
  #11  
Antiguo 22-10-2003
cesarjbf cesarjbf is offline
Miembro
 
Registrado: may 2003
Posts: 54
Poder: 21
cesarjbf Va por buen camino
Muchas gracias por responder...
El problema esta en que por cuestiones de hardware el usuario del aparato no cuenta mas que con dos botones para recorrer las imagenes, entonces solo queda la posibilidad de recorrerlas de 8 en 8 hasta las 1000 que existen, en realidad tendra que presionar 125 veces la tecla adelante para llegar desde la 0001 hasta la 1000, esto le tomara al usuario aproximadamente 60 segundos si es que tarda 60milisegundos entre serie y serie para recorrerlas todas, entonces cual seria la mas optima si en este momento esta tardando 1 minuto lo cual causa la desesperacion de los demas usuarios que quieren usar ell aparato?
Gracias.........
__________________
Mexicali
Responder Con Cita
  #12  
Antiguo 22-10-2003
Avatar de guillotmarc
guillotmarc guillotmarc is offline
Miembro
 
Registrado: may 2003
Ubicación: Huelva
Posts: 2.638
Poder: 24
guillotmarc Va por buen camino
Hola.

Si no quieres modificar la interfaz de usuario (añadir un pequeño TextBox con un SpinEdit opcional para indicar un salto a una imagen determinada). Entonces seguramente lo mejor será que utilizes un Thread (hilo de ejecución) secundario para cargar las imagenes (con la posiblidad de cancelar la carga antes que termine).

Eso te permite, que pulsen el botón, empiezen a cargarse las imagenes en un nuevo thread, y si cuando aún no han terminado de cargarse las imagenes, se vuelve a pulsar el botón, cancelas el thread que está cargando las imagenes, y abres un nuevo thread para cargar las ocho siguientes.

Consulta en la ayuda de Delphi, la clase TThread.

Saludos.
__________________
Marc Guillot (Hi ha 10 tipus de persones, els que saben binari i els que no).
Responder Con Cita
  #13  
Antiguo 22-10-2003
Avatar de guillotmarc
guillotmarc guillotmarc is offline
Miembro
 
Registrado: may 2003
Ubicación: Huelva
Posts: 2.638
Poder: 24
guillotmarc Va por buen camino
El thread te permite una gran velocidad de respuesta en el momento de darle a siguiente. Puesto que cuando le des a siguiente va a empezar a cargar immediatamente las siguientes 8 imagenes (aunque de las imagenes actuales solo haya llegado a mostrar 2, el resto no se llegaran a cargar al cancelarse el thread en que se hacia esa carga).

Si quieres optimizar la visualización de las siguientes 8 imagenes, puedes añadir dentro del thread la carga anticipada de las 8 imagenes siguientes y anteriores, que comenté en un mensaje anterior. Como la carga anticipada de imagenes también se hará dentro del thread secundario, si el usuario se mueve rápido entre las imagenes, la carga anticipada no se hará puesto que no finalizará el thread en que debe hacerse, por lo que no vamos a tener ninguna perdida de velocidad por esta causa. En cambio si el usuario se detiene unos segundos a mirar las imagenes, la carga anticipada finalizará correctamente al poder ejecutarse todo el thread, y cuando el usuario cambie a las siguientes imagenes, el efecto será que se cargan immediatamente (puesto que ya las tendremos en memoria). NOTA : Seguramente esta optimización de realizar una carga anticipada de imagenes, la deberías dejar como una segunda fase, programando primero que se carguen correctamente las imagenes a mostrar, en un Thread.

Saludos.
__________________
Marc Guillot (Hi ha 10 tipus de persones, els que saben binari i els que no).

Última edición por guillotmarc fecha: 22-10-2003 a las 14:50:50.
Responder Con Cita
Respuesta



Normas de Publicación
no Puedes crear nuevos temas
no Puedes responder a temas
no Puedes adjuntar archivos
no Puedes editar tus mensajes

El código vB está habilitado
Las caritas están habilitado
Código [IMG] está habilitado
Código HTML está deshabilitado
Saltar a Foro


La franja horaria es GMT +2. Ahora son las 07:08:39.


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
Copyright 1996-2007 Club Delphi