|
|||||||||||||||||||||||||||||||||||||||||||||||
|
Nous avons vu la dernière fois comment allouer un pinceau, afin de tracer une ligne (ou autre chose) de la couleur souhaitée. Tracer des lignes et afficher du texte, c'est bien beau, mais ça reste assez limité. Comment faire pour afficher une image en utilisant un algorithme qui fonctionne aussi bien sous AGA que sous CyberGraphX et Picasso96 ? Tout d'abord, l'image doit faire au maximum 256 couleurs pour pouvoir être affichée en AGA sur le Workbench. Nous allons donc nous limiter à des images de 256 couleurs maximum. Les écrans de 256 couleurs ou moins étant forcément basés sur une palette (chaque pixel contient le numéro d'un pinceau dans la palette et non pas directement la couleur RVB), il nous faut un format d'image dont les couleurs sont facilement recalculables dans la palette de l'écran. Le format Chunky est idéal pour cela : chaque pixel tient dans un octet ayant pour valeur le numéro de pinceau dans la palette de l'image. De plus, la graphics.library d'AmigaOS contient des fonctions servant à tracer des images à ce format. Convertir une image en chunky Vous pourriez croire le contraire, mais il n'existe, à ma connaissance, aucun outil permettant de convertir facilement une image en un fichier contenant des données au format chunky directement utilisables par un programme C. Il existe différents outils faisant plus ou moins ce que l'on désire, mais, malheureusement, soit ils le font plutôt moins que plus, soit ils sont bogués. En définitive, j'ai choisi Personal Paint et ArtPro. Personal Paint n'est pas indispensable, mais il est très utile pour réduire le nombre de couleurs d'une image en voyant en temps réel le résultat, et ceci vers un nombre quelconque de couleurs, pas seulement une puissance de 2. Quand à ArtPro, il permet à priori de faire tout ce dont on a besoin, y compris la conversion 24 bits vers un nombre quelconque de couleurs (sans prévisualisation), mais il n'est malheureusement pas exempt de bogues. GfxMaster permet également de sauver des images chunky, mais il est moins puissant. A essayer en cas de problèmes avec ArtPro, mais vous aurez alors probablement besoin d'un outil pour convertir un fichier binaire en source C, ou d'un assembleur pour créer un objet reliable. 1. Réduction du nombre de couleurs Chargez votre image dans Personal Paint, puis utilisez le menu "Couleurs->Moins de couleurs..." pour réduire le nombre de couleurs. Il vaut mieux diminuer le nombre de couleurs au maximum acceptable à ce moment, car le Workbench ne dispose que de 256 pinceaux au total ; donc si votre image utilise 256 couleurs différentes, il est très peu probable que toutes ses couleurs soient les bonnes une fois affichée sur le Workbench. Si vous utilisez un programme de dessin pour réduire le nombre de couleurs, le résultat sera bien meilleur que si vous laissez ObtainBestPen() faire tout le travail. Si votre image utilise un nombre de couleurs différent d'une puissance de 2, faites bien attention à ce que toutes les couleurs inutilisées de la palette soient les mêmes qu'une couleur utilisée... Sinon, des pinceaux seront alloués inutilement ! Si nécessaire, recopiez la couleur 0 dans toutes les couleurs non utilisées de la palette. Une autre solution est de noter le nombre de couleurs utilisées et de s'en servir par la suite pour n'allouer que le nombre de couleurs nécessaire (explications ci-dessous). 2. Conversion en chunky Lancez ArtPro, et vérifiez dans les réglages que le mode d'écran ("Screenmode") et les autres options sont corrects ; ça peut toujours servir. Chargez votre image en cliquant sur "Load" (Charger). En cas de problème, choisissez un chargeur approprié en cliquant sur "1". Si votre image n'a pas été réduite en 256 couleurs ou moins, cliquez sur "3" et choisissez un mode 8 bits ou inférieur. Cliquez ensuite sur "Render Ctrl" (contrôle du rendu), réglez "Mode" sur "Palette", puis choisissez le nombre de couleurs. Si vous voulez un nombre de couleurs différent d'une puissance de 2, cochez "Custom Palette" (palette personnalisée) et entrez le nombre désiré dans "Colors Used" (couleurs utilisées). Ensuite, cliquez sur "Render" (faire le rendu). Cliquez pour faire disparaitre l'image. Maintenant, cliquez sur "2" pour choisir le format de sauvegarde. Choisissez "Chunky". Cliquez sur "Config" (configuration) et sélectionnez :
Éditez ce fichier pour changer le nom du tableau généré. Appelez-le par exemple "image" (au lieu de "data"). Il faut aussi sauver la palette. Cliquez à nouveau sur "2", choisissez "Palette" et cliquez sur "Config" (configuration) et sélectionnez :
Cette opération crée un fichier contenant un tableau avec des "ULONG" décrivant la palette, au format LoadRGB32. Le premier ULONG contient dans ses 16 bits de poids fort le nombre de couleurs de la palette, et dans ses 16 bits de poids faible le numéro du premier pinceau à utiliser (vous pouvez l'ignorer pour cette fois). Ensuite, suivent les couleurs proprement dites, à raison de trois ULONG par couleur (Rouge, Vert, Bleu). Enfin, le dernier ULONG vaut toujours zéro. Vous remarquerez au passage qu'ArtPro ne calcule pas les valeurs des couleurs comme je l'ai expliqué dans le précédent article, mais se contente de rajouter des 0 dans les 24 bits de poids faible... Ce qui n'est certe pas gênant actuellement, vu que seuls les huit premiers bits sont pris en compte dans le meilleur des cas. Si vous voulez une palette avec un nombre de couleurs différent d'une puissance de 2, éditez le fichier "palette.h". Remplacez les 16 bits de poids fort de la première valeur du tableau par le nombre de couleurs effectif. Par exemple, si votre palette ne fait que 200 couleurs (0xc8) au lieu de 256 (0x100), remplacez "0x01000000" par "0x00c80000". Ensuite, supprimez toutes les couleurs en trop à la fin du tableau. Changez le nom du tableau de "data" en "palette" ; et puis rajoutez un retour à la ligne à la fin des deux fichiers, car ça peut poser des problèmes... Afficher l'image... Trois choses à faire :
Nous allons simplement balayer le tableau "palette" et allouer chaque pinceau comme expliqué dans le précédent article. Les numéros des pinceaux obtenus seront stockés dans un tableau afin de pouvoir recalculer les couleurs de la palette de l'image chunky, puis libérer les pinceaux à la fin du programme. Le premier UWORD du tableau est le nombre de couleurs de la palette. Le second peut ici être ignoré et devrait valoir 0.
Pour varier un peu, j'ai rajouté cette fois-ci une balise (OBP_Precision) permettant de choisir la précision de la couleur obtenue. PRECISION_ICON signifie que l'on n'y accorde pas beaucoup d'importance... Mais cela ne veut pas dire que les couleurs seront forcément mauvaises :-). Recalculer les couleurs de la palette de l'image ("remap") Maintenant, afficher l'image telle quelle ne marcherait pas : elle n'aurait pas les bonnes couleurs. En effet, si dans notre palette la couleur 0 est du noir, ce n'est pas le cas de la palette du Workbench qui contient généralement du gris en position 0. Le pinceau qu'on a obtenu en faisant un ObtainBestPen() sur cette couleur ne vaut donc certainement pas 0. Il faut donc changer tous les 0 de l'image chunky en la valeur obtenue par ObtainBestPen() sur la couleur 0 de notre palette... et faire de même pour toutes les autres couleurs.
Vous le voyez, c'est une opération extrêmement simple. Je suppose ici que les constantes IMAGE_WIDTH et IMAGE_HEIGHT ont été définies et valent respectivement la largeur et la hauteur de l'image à afficher. Tracer l'image Enfin, il ne reste plus qu'à tracer l'image chunky obtenue. Il existe deux fonctions de la graphics.library permettant de faire cela : WritePixelArray8() et WriteChunkyPixels(). La première est disponible sous AmigaOS 3.0 mais nécessite l'allocation d'un RastPort temporaire et ne fonctionne qu'avec une image multiple de 16 pixels en largeur, tandis que la seconde n'existe que depuis AmigaOS 3.1 et est plus simple d'utilisation. Une autre chose à noter en ce qui concerne WritePixelArray8() est que cette fonction efface l'image chunky ! (note : si j'en crois le fichier "readme" de NewWPA8, ce bogue affecte aussi WriteChunkyPixels(); mais ceci ne concerne pas les utilisateurs de cartes graphiques). Nous utiliserons ici WriteChunkyPixels().
Voyez l'AutoDoc de WriteChunkyPixels() pour les détails. Voici le programme final, reprenant en partie la base mise en place dans les articles précédents. N'oubliez pas d'adapter IMAGE_WIDTH et IMAGE_HEIGHT à la taille de votre image.
Vous pouvez voir que, dans un souci de simplification, il n'y a plus d'ouverture de bibliothèques. En effet, la plupart des compilateurs disposent d'un mécanisme d'ouverture automatique des bibliothèques système telles qu'intuition.library et graphics.library (avec vbcc, il suffit de rajouter "-lauto" sur la ligne de commande). L'inconvénient de cette méthode est qu'on a moins de contrôle sur les versions des bibliothèques et qu'on ne peut pas afficher de message d'erreur adéquat en cas d'échec. Mais afin de ne pas surcharger les programmes d'exemple, j'ai décidé de laisser faire le compilateur ; vous pouvez toujours remettre les ouvertures et fermetures de bibliothèques si nécessaire. Une précision importante au sujet de la libération des pinceaux que j'ai oubliée de mentionner dans le précédent article : si vous libérez un pinceau alors que votre image est toujours affichée, ses couleurs risquent de changer si un autre programme alloue lui aussi des pinceaux à ce moment-là. Donc il ne faut libérer les pinceaux qu'une fois que l'image n'est plus visible ! A noter cependant que ce problème ne se pose pas sur les écrans HiColor/TrueCOlor, puisqu'ils ne sont pas réellement palettisés... Enfin, si votre application utilise beaucoup WriteChunkyPixels(), recommandez à vos utilisateurs sous AGA l'installation d'un correctif tel que NewWPA8 ou BlazeWCP qui accélère énormément les fonctions de tracé chunky. De plus, il devrait corriger le bogue de WritePixelArray8() faisant que l'image est effacée lors du tracé.
|