2009-05-07 17 views
5

Necesito mostrar miniaturas de imágenes en un directorio determinado. Uso TFileStream para leer el archivo de imagen antes de cargar la imagen en un componente de imagen. El mapa de bits luego se redimensiona al tamaño de miniatura y se asigna a un componente TImage en un TScrollBox.¿Cuál es la forma más rápida de cargar y cambiar el tamaño de una imagen?

Parece que funciona bien, pero se ralentiza bastante con imágenes más grandes.

¿Hay una manera más rápida de cargar archivos (imágenes) del disco y redimensionarlos?

Gracias, Pieter

Respuesta

5

Realmente no. Lo que puede hacer es redimensionarlos en un subproceso de fondo y usar una imagen de "posición de posición" hasta que finalice el cambio de tamaño. Luego guardaría estas imágenes redimensionadas en algún tipo de archivo de caché para su posterior procesamiento (Windows hace esto y llama a la memoria caché thumbs.db en el directorio actual).

Tiene varias opciones en la arquitectura de subprocesos. Un solo hilo que hace todas las imágenes, o un grupo de hilos donde un hilo solo sabe cómo procesar una sola imagen. La biblioteca AsyncCalls es incluso otra manera y puede mantener las cosas bastante simples.

+0

Mi aplicación ahora usa marcadores de posición e hilos (skamradt, mghie) y funciona perfectamente.Las miniaturas se extraen según lo sugerido por Stijn Sanders. Gracias. Pieter. –

+0

Desafortunadamente, AsyncCalls está muerto (descontinuado). – Ampere

5

Completaré la respuesta de skamradt con el intento de diseñar esto para que sea lo más rápido posible. Para ello, debe

  • optimizar la E/S
  • uso de múltiples hilos para hacer uso de múltiples núcleos de CPU, y para mantener incluso un solo núcleo de la CPU de trabajo mientras se lee (o escribir) Archivos

El uso de varios subprocesos implica que el uso de clases VCL para el cambio de tamaño no va a funcionar, ya que el VCL no es seguro para subprocesos, y todos los ataques que no se escalan correctamente. efg's Computer Lab tiene enlaces para el código de procesamiento de imágenes.

Es importante no causar varias operaciones de E/S concurrentes cuando se utilizan varios subprocesos. Si elige volver a escribir las imágenes en miniatura en los archivos, una vez que haya comenzado a leer un archivo, debe leerlo por completo, y una vez que haya comenzado a escribir un archivo, también debe escribirlo por completo. Intercalar ambas operaciones matará a su E/S, porque potencialmente puede causar muchas operaciones de búsqueda de la cabeza del disco duro.

Para obtener los mejores resultados, la lectura (y escritura) de los archivos tampoco debería ocurrir en el hilo principal (GUI) de su aplicación. Eso sugeriría el siguiente diseño:

  • Tener un hilo leer archivos en objetos TGraphic, y poner estas en una lista de temas de seguridad.
  • Haga que un grupo de subprocesos espere en la lista de archivos en tamaño original, y haga que un subproceso procese un objeto TGraphic, cambie su tamaño a otro objeto TGraphic y añádalo a otra lista segura para subprocesos.
  • Notifique el hilo de la GUI para cada imagen en miniatura agregada a la lista, para que pueda mostrarse.
  • Si las miniaturas deben escribirse en un archivo, hágalo en el hilo de lectura también (consulte la explicación anterior).

Editar:

Al volver a leer su pregunta Me he dado cuenta de que tal vez sólo tendrá que cambiar el tamaño de una imagen, en cuyo caso un solo hilo de fondo es por supuesto bastante. Dejaré mi respuesta en su lugar de todos modos, tal vez sea útil para otra persona en algún momento. Es lo que aprendí de uno de mis últimos proyectos, donde el programa final podría haber necesitado un poco más de velocidad, pero solo estaba usando aproximadamente el 75% de la máquina de cuatro núcleos en las horas punta. El desacoplamiento de E/S del procesamiento hubiera marcado la diferencia.

5

A menudo uso TJPEGImage con Scale: = jsEighth (en Delphi 7). Esto es realmente rápido porque la compresión de JPEG puede omitir una gran cantidad de datos para llenar un mapa de bits de solo un octavo de ancho y alto.

Otra opción es utilizar el shell's method to extract a thumbnail, que es bastante rápido, así

+0

esto se ve bien. Estaba desesperado por resolver esto el año pasado, pero ahora ya no me importa demasiado. Pero aún puedo arreglar algunas de mis aplicaciones usando el enfoque TJPEGImage.Scale. Gracias –

1

estoy en el negocio de la visión, y simplemente subir las imágenes a la GPU usando OpenGL. (típicamente 20x 2048x2000x8bpp por segundo), un bmp por textura, y deje que la escala de la tarjeta de video (win32, encabezados opengl de Mike Lischke)

La carga de dicha imagen cuesta 5-10ms dependiendo de la tarjeta de video exacta (si no está integrada y nvidia 7300 serie o más reciente. También es posible realizar GPU integradas muy recientes). Escalar y visualizar cuesta 300us. Lo que significa que los clientes pueden desplazarse y acercarse como locos sin tocar la aplicación. Dibujé una superposición (que solía ser un archivo tmeta pero ahora es un formato propio) en la parte superior.

Mi imagen más grande es 4096x7000x8bpp que muestra y escala en menos de 30ms. (GF 8600)

Una limitación de esta tecnología es el tamaño máximo de la textura. Puede resolverse fragmentando la imagen en múltiples texturas, pero todavía no me he molestado porque entrego los sistemas con el software.

(algunos tamaños típicos: nv6x00 serie: 2k * 2k, pero la carga se trata sólo de un punto de equilibrio en comparación con GDI nv7x00 serie:. 4k * 4k Para mí las tarjetas de línea de base GF7300 de son como $ 20-40 nv8x00 serie: 8k * 8k )

Tenga en cuenta que esto puede no ser adecuado para todos. Pero si te encuentras en la situación afortunada de especificar límites de hardware, podría funcionar. El principal problema son las computadoras portátiles como los Thinkpads, las GPU de las cuales son más viejas que la computadora portátil avg, que a su vez a menudo están a una generación detrás de las computadoras de escritorio.

Escogí OpenGL por DirectX porque es más estático en el tiempo y más fácil de encontrar ejemplos no relacionados con el juego.

+0

muy informativo pero fuera del tema. –

+0

encontré esto para ser lo que estaba buscando. ¡gracias! –

0

Aproveche la capacidad de Windows para crear miniaturas. ¿Recuerdas que los archivos Thumbs.db están ocultos en las carpetas que contienen imágenes?

He implementado algo así como esta característica, pero en VB. Mi software puede crear miniaturas de 100 archivos (tamaño mixto) en alrededor de 10 segundos.

Aunque no puedo convertirlo a Delphi.

0

tratar de ver el Graphics32 library: es muy bueno en las cosas de dibujo y funciona gran de mapas de bits. Son Thread - Safe con buen ejemplo, y es totalmente gratis.

Cuestiones relacionadas