Question

Je dois afficher des vignettes d'images dans un répertoire donné. J'utilise TFileStream pour lire le fichier image avant de charger l'image dans un composant image. La bitmap est ensuite redimensionnée à la taille de la vignette et affectée à un composant TImage sur un TScrollBox.

Cela semble fonctionner correctement, mais ralentit beaucoup avec des images plus grandes.

Existe-t-il un moyen plus rapide de charger des fichiers (images) à partir du disque et de les redimensionner?

Merci, Pieter

Était-ce utile?

La solution

Pas vraiment. Ce que vous pouvez faire est de les redimensionner dans un fil d’arrière-plan et d’utiliser un "espace réservé". image jusqu'à ce que le redimensionnement soit terminé. Je voudrais ensuite enregistrer ces images redimensionnées dans une sorte de fichier cache pour un traitement ultérieur (Windows effectue cette opération et appelle le cache thumbs.db dans le répertoire en cours).

Vous avez plusieurs options sur l'architecture du fil elle-même. Un seul thread qui traite toutes les images ou un pool de threads dans lequel un thread ne sait comment traiter qu'une seule image. La bibliothèque AsyncCalls est même un autre moyen et permet de garder les choses simples.

Autres conseils

Je compléterai la réponse de skamradt en essayant de le concevoir de manière à être aussi rapide que possible. Pour cela, vous devriez

  • optimiser les E / S
  • utilisez plusieurs threads pour utiliser plusieurs cœurs de processeur et conserver le fonctionnement d'un seul cœur de processeur pendant la lecture (ou l'écriture) de fichiers

L'utilisation de plusieurs threads implique que l'utilisation des classes VCL pour le redimensionnement ne fonctionne pas, car la VCL n'est pas adaptée aux threads et toutes les pirouettes autour de celles-ci ne sont pas correctement dimensionnées. Le le laboratoire informatique d'efg contient des liens pour le code de traitement d'images.

Il est important de ne pas provoquer plusieurs opérations d'E / S simultanées lors de l'utilisation de plusieurs threads. Si vous choisissez d'écrire les images miniatures dans des fichiers, vous devez le lire intégralement une fois que vous avez commencé à lire le fichier. Une fois que vous avez commencé à écrire un fichier, vous devez également l'écrire complètement. Le fait d'entrelacer les deux opérations tuera vos E / S, car vous risquez de provoquer de nombreuses opérations de recherche de la tête de disque dur.

Pour obtenir de meilleurs résultats, la lecture (et l'écriture) de fichiers ne devrait pas non plus se produire dans le fil principal (GUI) de votre application. Cela suggérerait le design suivant:

  • Demandez à un thread de lire les fichiers dans des objets TGraphic et de les placer dans une liste sans danger de thread.
  • Demandez à un pool de threads d'attendre la liste de fichiers dans sa taille d'origine et demandez à un thread de traiter un objet TGraphic, de le redimensionner en un autre objet TGraphic et de l'ajouter à une autre liste protégée par des threads.
  • Informez le fil de l'interface graphique de chaque image miniature ajoutée à la liste afin qu'elle puisse être affichée.
  • Si des miniatures doivent être écrites dans un fichier, faites-le également dans le fil de lecture (voir ci-dessus pour une explication).

Modifier:

En relisant votre question, je remarque que vous n’avez peut-être besoin que de redimensionner une image. Dans ce cas, un seul fil d’arrière-plan suffit bien entendu. De toute façon, je laisserai ma réponse, elle sera peut-être utile à quelqu'un d'autre quelque temps. C'est ce que j'ai appris de l'un de mes derniers projets, où le programme final aurait pu nécessiter un peu plus de vitesse mais n'utilisait que 75% environ de la machine quad core dans les heures de pointe. Découpler les E / S du traitement aurait fait la différence.

J'utilise souvent TJPEGImage avec Scale: = jsEighth (sous Delphi 7). C’est très rapide, car la décompression JPEG peut ignorer une grande partie des données pour remplir une image bitmap d’un huitième de largeur et de hauteur.

Une autre option consiste à utiliser la méthode du shell pour extraire une vignette , ce qui est assez rapide bien

Je suis dans le secteur de la vision et je télécharge simplement les images sur le GPU à l'aide d'OpenGL. (généralement 20x 2048x2000x8bpp par seconde), un bmp par texture, et laissez la carte vidéo redimensionner (win32, les en-têtes opengl de Mike Lischke)

Le téléchargement d’une telle image coûte 5 à 10 ms, en fonction de la carte vidéo exacte (s’il n’est pas intégré et que la série NVIDIA 7300 ou une version plus récente est plus récente. Des GPU intégrés très récents peuvent également être réalisables). La mise à l'échelle et l'affichage coûtent 300us. Ce qui signifie que les clients peuvent effectuer un panoramique et un zoom comme un fou sans toucher l'application Je dessine un calque (qui était autrefois un fichier tmetafile mais qui est maintenant un format propre).

Ma plus grande image est 4096x7000x8bpp, ce qui montre et réduit en moins de 30ms. (8600 GF)

Une limite de cette technologie est la taille maximale de la texture. Vous pouvez résoudre ce problème en fragmentant l’image en plusieurs textures, mais je n’ai pas encore pris la peine de le faire car je livre les systèmes avec le logiciel.

(certaines tailles typiques: Série nv6x00: 2k * 2k mais le téléchargement est presque rentable par rapport à GDI Série nv7x00: 4k * 4k Pour moi, les cartes de base. GF7300 sont comme 20-40 $ série nv8x00: 8k * 8k )

Notez que cela pourrait ne pas être pour tout le monde. Mais si vous avez la chance de spécifier des limites matérielles, cela pourrait fonctionner. Le problème principal concerne les ordinateurs portables tels que les Thinkpads, dont les GPU sont plus anciens que les ordinateurs portables avg, qui sont souvent une génération derrière les ordinateurs de bureau.

J'ai choisi OpenGL plutôt que DirectX car il est plus statique dans le temps et plus facile à trouver. Des exemples non liés au jeu.

Essayez de regarder la bibliothèque Graphics32 : elle est très douée pour dessiner et travailler excellent avec Bitmaps. Ils sont Thread - Safe avec bon exemple, et c'est totalement gratuit.

Exploitez la capacité de Windows pour créer des vignettes. N'oubliez pas que les fichiers Thumbs.db cachés dans les dossiers contenant des images?

J'ai implémenté quelque chose comme cette fonctionnalité mais en VB. Mon logiciel est capable de créer des vignettes de 100 fichiers (taille mixte) en 10 secondes environ.

Je ne parviens pas à le convertir en Delphi cependant.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top