Prise en charge d'images High-DPI avec les composants Collection d'images et Liste d'images virtuelles

De RAD Studio
Aller à : navigation, rechercher

Présentation

RAD Studio vous permet d'inclure des images redimensionnables, à résolution multiple et à haute résolution dans vos applications VCL Windows par l'intermédiaire du composant TImageCollection et en association avec le composant TVirtualImageList.

Attention: Si vous utilisez FireMonkey en vue de créer des applications multiplates-formes, reportez-vous au composant TImageList et au guide FireMonkey pour employer les TImageList comme des référentiels d'images.

Ces deux composants correspondent à deux concepts distincts : une collection d'images (chaque image logique peut avoir plusieurs résolutions) et une liste d'images ayant une taille spécifique pour un contrôle. Une collection d'images peut charger plusieurs résolutions d'images. La liste d'images contient un ensemble d'images dont la source est une collection d'images. Ces images sont ensuite présentées à une taille spécifique (16x16, par exemple.) Les images sont redimensionnées et mises à l'échelle alors que la résolution de la présentation actuelle peut changer en fonction de la résolution (DPI). Cette fonctionnalité est entièrement compatible avec les listes d'images traditionnelles (y compris en fournissant un handle HIMAGELIST) et peut être utilisée avec des contrôles VCL et tout code utilisant des appels à des listes d'images API Windows.

Les images prennent en charge les canaux alpha. Vous pouvez aussi charger des fichiers PNG dans la collection d'images. Il est également possible de charger des bitmaps utilisant la transparence avec incrustation de couleurs.

Utilisation du composant Collection d'images

TImageCollection vous permet de stocker, mettre à l'échelle et dessiner des images ayant des formats natifs en utilisant la classe TWICImage.

Chaque image de la collection peut avoir plusieurs versions, chacune ayant une taille différente. Le composant choisit la taille optimale pour la mise à l'échelle ou utilise une image si la taille disponible est équivalente à la taille requise. Il peut aussi créer une version TBitmap 32 bits mise à l'échelle avec un canal alpha et pouvant être ajoutée directement au TCustomImageList.

TImageCollection est héritée de la classe TCustomImageCollection (unité Vcl.BaseImageCollection), qui définit les méthodes de base d'une collection.

Editeur de composant Collection d'images

Pour ouvrir l'éditeur de collection d'images, placez un TImageCollection sur une fiche ou un module de données et double-cliquez sur le composant ou cliquez avec le bouton droit et sélectionnez Afficher l'éditeur de collection... dans le menu contextuel. Vous pouvez également double-cliquer sur la propriété TImageCollection.Images dans l'inspecteur d'objets.

La fenêtre de l'éditeur de collection d'images vous permet d'ajouter des images au composant et de les organiser par catégories.

Remarque: Pour pouvoir reconnaître les différentes tailles d'une même image, l'éditeur de collection d'images requiert d'utiliser un séparateur dans le numéro du nom de fichier.

Cliquez sur Ajouter pour afficher la boîte de dialogue Ouvrir et naviguez jusqu'au dossier dans lequel vos images sont stockées. Les images peuvent être ajoutées les unes après les autres ou vous pouvez effectuer une sélection multiple depuis un dossier et ajouter les images simultanément. L'éditeur de collection d'images affiche les images par ordre alphabétique.

Fichier:ImageCollectionEditor Update.png

Sélectionnez la case à cocher Vérifier la taille dans le nom de fichier pour rechercher des informations sur la taille de l'image dans le nom de fichier lors de l'ajout des images. Vous pouvez aussi sélectionner un séparateur de taille d'image dans les options des listes déroulantes. Il s'ensuit une reconnaissance des résolutions multiples d'une même image ayant des noms de fichiers similaires à l'exception de l'indication sur la taille de fichier. Elles sont ensuite ajoutées comme résolutions multiples d'une même image dans la collection.

Le paramètre Séparateur de taille d'image permet de définir comment la taille de l'image est analysée et contient des options relatives aux conventions de nommage des fichiers image et aux icônes communes.

Conseil: Utilisez le bouton Ajouter… en haut à droite pour ajouter plusieurs sources pour une image de la collection. Lorsque vous ajoutez plusieurs sources, assurez-vous que les fichiers source comportent le même nom de fichier que le premier ensemble d'images ajouté à la collection.
Pour ajouter des sources à une image spécifique, sélectionnez l'image dans la collection et cliquez sur Ajouter… en bas de la fenêtre de façon à afficher la boîte de dialogue Ouvrir et localiser le fichier image.

Les catégories ne sont utilisées qu'à des fins d'organisation. (Dans les contrôles VCL, les images sont toujours référencées par leur indice.)

Pour organiser des images dans une catégorie, sélectionnez les images et cliquez sur Définir la catégorie.

Utilisez le bouton Supprimer dans la section supérieure pour supprimer des images spécifiques de la collection, et le bouton Effacer pour retirer toutes les images de la collection.

Attention: Si vous souhaitez supprimer une image de la collection, vous devez savoir que le composant VirtualImageList utilise l'index pour rechercher les images.

Une fois les images ajoutées à la collection, vous pouvez sélectionner l'une des images disponibles et réaliser les actions suivantes :

  • Modifier le nom de l'image.
  • Assigner une description personnalisée à l'image.
  • Assigner une valeur d'index pour modifier l'ordre des images à l'intérieur de la collection.
  • Ajouter des sources supplémentaires pour une même image.
  • Supprimer une source de l'image.
  • Remplacer une source existante d'une image.
Attention: Suivez les étapes ci-dessous pour renommer et remplacer une image :
  • Modifier index[nom] et Appliquer les modifications (VirtualImageList actualise les images par index [nom] en utilisant le nom [index] de la collection).
  • Modifier nom [index] et Appliquer les modifications (VirtualImageList actualise les images par nom[index] en utilisant l'index [nom] dans la collection).
  • Enregistrer une image sous un autre nom (Enregistrer sous...).
Conseil: Vous pouvez aussi cliquer et faire glisser une image à une autre position pour modifier sa valeur d'index.

Chargement d'un TImageList existant dans un TImageCollection

Pour convertir des listes d'images d'ancien style en collection d'images de nouveau style, vous pouvez charger des images d'un TImageList dans un TImageCollection. Si vous avez plusieurs tailles d'une même image dans différents TImageLists, vous pouvez les charger en une seule fois, les images sont fusionnées afin que la collection d'images contienne plusieurs résolutions de la même image.

Pour pouvoir charger des images d'un TImageList dans un TImageCollection, les deux composants doivent être préalablement placés sur une même fiche.

Suivez les étapes ci-dessous pour charger des images d'un TImageList existant dans un TImageCollection de la même fiche :

  1. Cliquez avec le bouton droit de la souris sur le composant TImageCollection de la fiche et sélectionnez l'option Charger à partir du TImageList existant… dans le menu contextuel.
  2. Sélectionnez le TImageList que vous voulez charger et assignez une catégorie aux images. Vous pouvez sélectionner plusieurs TImageList. Cela s'avère particulièrement utile si vous voulez charger plusieurs résolutions de la même image précédemment stockées dans plusieurs listes d'images.
    LoadFromTImageList Load.png
  3. Cliquez sur Charger dans l'ordre pour charger les images dans le même ordre que la liste d'images.
  4. Cliquez sur Charger et fusionner pour fusionner différentes sources d'images à partir de différentes listes d'images. Dans ce cas, les listes d'images doivent avoir le même nombre de fichiers images mais des tailles d'images différentes.
    LoadFromTImageList LoadWithMerging.png
  5. Cliquez sur Voir la collection… pour voir comment les images sont importées dans le TImageCollection sans fermer la boîte de dialogue.
  6. Cliquez sur OK pour appliquer les paramètres et fermer la boîte de dialogue.
  7. Cliquez sur Appliquer pour appliquer un ensemble de modifications et continuer la configuration.
  8. Cliquez sur Annuler pour fermer la boîte de dialogue en annulant les modifications apportées à la collection d'images.
Attention: Si vous constatez que des images ne sont pas correctement restituées une fois importées depuis un TImageList dans un TImageCollection ou un TVirtualImageList, (bords blancs ou autres effets), vérifiez la propriété ColorDepth du TImageList. Il arrive que cette propriété du TImageList FMX soit définie sur cd32Bit alors que les images qu'il contient sont en fait des images 24 bits ou 16 bits. Assurez-vous que la profondeur de couleur du TImageList est définie sur cd32Bit si les bitmaps qu'il contient sont véritablement des bitmaps 32 bits, canal alpha y compris.

Utilisation du composant TVirtualImageList

TVirtualImageList vous permet de générer une liste d'images et d'appliquer les modifications à l'ensemble des images simultanément.

TVirtualImageList utilise TCustomImageCollection (TImageCollection) pour générer une liste dynamique des images internes.

Avec TVirtualImageList, vous pouvez définir des propriétés personnalisées pour la hauteur et la largeur. Le composant effectue automatiquement la mise à l'échelle des images. Dès que la résolution DPI change, les images sont mises à l'échelle de façon à s'afficher correctement sur des écrans à haute résolution.

Remarque: TVirtualImageList hérite automatiquement de la résolution DPI de son propriétaire (TCustomForm ou TCustomFrame) lors de la mise à l'échelle.
Les contrôles VCL peuvent utiliser TVirtualImageList sans modifications car il est dérivé de TCustomImageList.
Remarque: Pour ajouter, insérer et/ou remplacer des bitmaps dans TVirtualImageList, vous devez utiliser des méthodes pour ajouter, insérer et/ou remplacer des éléments de ImageCollection.

L'éditeur de composant TVirtualImageList

Pour pouvoir utiliser le composant TVirtualImageList et l'éditeur de composant, vous devez d'abord définir la propriété ImageCollection dans l'inspecteur d'objets.

VImageList ObjectInspector.png

Pour ouvrir l'éditeur de TVirtualImageList, vous pouvez double-cliquer sur le composant dans la fiche ou cliquer avec le bouton droit de la souris et sélectionner l'option Afficher l'éditeur de liste d'images... dans le menu contextuel.

Si vous définissez la propriété AutoFill sur True, la liste d'images virtuelles sera remplie automatiquement avec les images de la collection. Vous pouvez aussi ajouter manuellement des images de la collection en utilisant l'éditeur de liste d'images.

Fichier:VirtualImageList Editor Update.png

La fenêtre Editeur de liste d'images virtuelles vous permet d'ajouter des images au composant, d'inclure des versions désactivées des images et de les organiser sous forme de catégories.

Cliquez sur Ajouter pour ouvrir la collection d'images associée et sélectionnez les images à inclure dans la liste d'images virtuelles. Vous pouvez sélectionner des images spécifiques dans la collection d'images ou sélectionner toutes les images dans la collection ou dans une catégorie existante.

De plus, la fenêtre de l'éditeur de liste d'images virtuelles comporte les options suivantes :

  • Ajouter Désactivé : vous permet de créer et d'ajouter des versions grisées ou de moindre opacité des images que vous sélectionnez. L'apparence des images désactivées est définie par les propriétés DisabledGrayscale et DisabledOpacity de la liste d'images.
  • Ajouter avec une copie en Désactivé : vous permet d'ajouter des images à partir de la collection d'images associée et de créer et d'ajouter simultanément des versions désactivées des images sélectionnées.
  • Remplacer : vous permet de remplacer une image sélectionnée.
Attention: Vous pouvez uniquement remplacer une image du composant TVirtualImageList par une image provenant du composant Collection d'images ne se trouvant pas dans la liste d'images précédemment ajoutée.
  • Définir la catégorie : vous permet de regrouper des images dans des catégories. Pour créer une catégorie, sélectionnez les images à inclure dans la catégorie et cliquez sur Définir la catégorie…, entrez le nom de la catégorie et cliquez sur OK pour l'afficher dans la liste des catégories. L'éditeur de composant ajoute le nom de la catégorie au nom de l'image.
  • Changer tout en Désactivé : convertit les images précédemment ajoutées en images désactivées.

Fichier:VirtualImageList Editor.png

Après avoir ajouté des images au composant TVirtualImageList, vous pouvez effectuer les actions suivantes :

  • Recharger : Recharge les noms et descriptions de l'image à partir de la collection d'images.
  • Supprimer : retire du composant TVirtualImageList la ou les images sélectionnées.
  • Effacer : retire toutes les images de la collection.
  • Nom : Modifier le nom de l'image.
  • Description : Assigne une description personnalisée à l'image.

Utilisation du composant Image avec des résolutions multiples

Le composant TVirtualImage prend en charge plusieurs résolutions pour les composants de type TImage. La source des images vient d'un TImageCollection, et vous pouvez avoir plusieurs résolutions selon la résolution (DPI). Le composant utilise la version adaptée selon le moniteur affiché.

Le composant TVirtualImage possède les propriétés et les paramètres suivants : ImageCollection, ImageHeight, ImageIndex, ImageName et ImageWidth.

TVirtualimage.png

Si vous utilisez la logique de mise à l'échelle du bitmap pour dessiner un TGraphic de la VCL lorsqu'il est mis à l'échelle (par ex. StretchDraw), une classe TScaledGraphicDrawer permet d'activer la mise à l'échelle de haute qualité à la volée pour différentes classes de TGraphic avec des appels comme :

MyBitmap.EnableScaler(TD2DGraphicScaler);
Image1.Picture.Graphic.EnableScaler(TWICGraphicScaler);

Différentes solutions offrent des combinaisons de restitution et de performances plus ou moins bonnes. Vous pouvez écrire des classes héritées de TScaledGraphicDrawer définissant des algorithmes de mise à l'échelle supplémentaires.

Bonnes pratiques

Les composants TVirtualImageList sont mis à l'échelle avec la résolution DPI de la fiche sur laquelle ils sont placés. Cela permet aux contrôles de la fiche qui sont dessinés avec la liste d'images d'être toujours dessinés à la bonne résolution. Toutefois, cela implique les deux considérations suivantes :

  • Les contrôles doivent toujours faire référence à une liste d'images sur la même fiche. Si un contrôle fait référence à une liste d'images d'une autre fiche, les images risquent de ne pas s'afficher correctement si elles ont une résolution DPI différente.
  • Un composant TVirtualImageList doit toujours être placé sur une fiche et non sur un module de données. Les fiches sont associées à un moniteur et une résolution DPI, ce qui n'est pas le cas des modules de données. Un TImageCollection peut être placé n'importe où car il fait simplement référence à la source des images, et n'est pas affecté par les changements de résolution DPI : il contient la source des images, alors que la liste des images virtuelles correspond à la présentation.

Ainsi, si des contrôles d'une fiche utilisent une liste d'images, placez toujours un ou plusieurs TVirtualImageList sur cette fiche et configurez les contrôles pour qu'ils fassent référence aux listes d'images de cette même fiche. Ces composants TVirtualImageList peuvent tous faire référence au même composant TImageCollection.

La collection d'images virtuelles est un contrôle très utile, qui a pour avantage d'associer le concept d'une collection d'images (TImageCollection) à un ensemble d'images d'une taille spécifique s'ajustant à la résolution DPI (TVirtualImageList). Une collection d'images n'est pas concernée par les changements de résolution DPI car elle a un rôle de conteneur. Les listes d'images virtuelles peuvent faire référence à une collection d'une autre fiche ou d'un module de données. Il est recommandé d'avoir une seule collection d'images pour des images qui sont plus ou moins apparentées (par ex. les images de barre d'outils et de menus) et de la placer sur la fiche principale de votre application ou dans un module de données partagé. Les autres fiches auront leurs propres listes d'images virtuelles qui utiliseront la collection d'images centrale.

Tailles multiples

Si vous avez besoin d'avoir plusieurs tailles d'une même image (par ex. pour les propriétés SmallImages et LargeImages de TListView), utilisez deux composants TVirtualImageList comme vous le faites habituellement avec les TImageList traditionnels. Les deux listes d'images virtuelles peuvent faire référence à la même collection d'images.

Prise en charge de la haute résolution dans vos applications : conversion des anciens TImageList

Il est fréquent de convertir des applications VCL en remplaçant les TImageList par des TVirtualImageList en vue d'améliorer la qualité visuelle et de prendre en charge la haute résolution.

TVirtualImageList est un descendant de TCustomImageList. Il faut donc effectuer un changement au niveau du code et fournir un handle de propriété HIMAGELIST pour appeler directement les méthodes de l'API Windows.

Nous recommandons les deux approches suivantes pour convertir votre app de façon à utiliser les nouvelles listes d'images Haute résolution.

Premièrement, vous pouvez en profiter pour mettre à jour vos icônes et opter pour un style plus moderne ou choisir un effet de transparence pour les images 32 bits avec un canal alpha. Dans ce cas, il est parfois plus simple d'ajouter simplement ces images à une nouvelle collection d'images, de créer de nouvelles listes d'images et de modifier vos composants pour qu'ils pointent sur les nouvelles listes d'images.

Deuxièmement, vous pouvez procéder étape par étape, en remplaçant les anciennes images les unes après les autres ou en ne les remplaçant pas (bien qu'il soit conseillé de profiter du nouveau système prenant en charge le canal alpha 32bpp). Pour cela, placez un TImageCollection et cliquez avec le bouton droit puis sélectionnez Charger à partir du TImageList existant. Sélectionnez les listes d'images et choisissez d'ajouter une image ou de fusionner des images si elles contiennent la même image sous différentes résolutions. Voir TImageList dans TImageCollection, Chargement d'un TImageList existant dans un TImageCollection pour plus d'informations.

Votre collection d'images contiendra ainsi les anciennes images. Si vous utilisez des images anciennes, vous ne pourrez pas constater une nette amélioration en qualité graphique ou en transparence comme cela aurait été le cas si vous aviez utilisé des images nouvellement conçues. Cela vous permet essentiellement de mettre à l'échelle des images en fonction de la résolution DPI de chaque fiche. Créez de nouveaux composants TVirtualImageList sur chaque fiche et ajoutez les images à partir de la collection : elles garderont ainsi leur ordre relatif et leur index sauf s'il y avait déjà des images dans la collection. Modifiez ensuite les composants de façon à utiliser le nouveau composant TVirtualImageLists.

Mise à l'échelle progressive lors d'un dessin sur un TCanvas

TCanvas.StretchDraw permet de dessiner un TGraphic sur un rectangle arbitraire. L'implémentation de sous-classe TGraphic détermine comment s'effectue le dessin. En pratique, le dessin VCL (comme pour un TBitmap) utilise généralement un ré-enchantillonage du voisin le plus proche via GDI, ce qui provoque généralement une image mise à l'échelle ou étirée de qualité médiocre.

Vous pouvez utiliser un TImageCollection pour contenir une image (stockée en interne et dessinée avec WIC) et la dessiner sur un rectangle arbitraire. Ce processus utilise un ré-enchantillonage de haute qualité.

Voir aussi