

Palettemap()
#1
Posté 28 November 2012 - 16:37 PM
Pour ceux qui avait déjà vue mon ancien post sur la duplication d'un tableau provenant d'une classe, je suis toujours dans le même projet, juste une étape plus éloigner.
Sinon pour les autres je vais brièvement résumer la partie du projet sur laquelle je bloque.
J'importe une image dans un bitmap que j'ai créer. (donc l'image s'affiche dans le bitmap et on distingue bien les pixels)... Jusque là tous va bien.
Cependant maintenant je souhaiterais pouvoir modifier tous les pixels de cette image pour qu'ils soient d'une couleur correspondante à ma palette.
J'ai beau cherché je ne trouve pas de réel exemple sur l'utilisation de la fonction palettemap(), en tous cas rien de très précis.
Car je sais que pour la fonction palettemap() nous créons par la suite 4 tableaux (redArray, greenArray, blueArray, alphaArray) mais ma question est qu'est ce qui vient apparaître dans ces tableaux. (oui c'est surement bête mais je suis perdu...)
Est ce que dans ces tableaux doivent y être inscrit uniquement la valeur de R pour le redArray, G pour le greenArray etc...
Et peut être que c'est pas du tous possible avec cette fonction.
Désolé je n'ai pas de code disponible pour le moment mais se soir j'essaierais de vous poster un petit test effectuer.
Merci d'avance.
#2
Posté 28 November 2012 - 20:39 PM
Content de voir que tu avances. Et... je comprends très bien ta question


Voici comment je comprends la documentation de cette fonction:
Si tu veux, par exemple, transformer les pixels de couleur ( R,V,B )=(10,20,30) en pixels de couleur (60, 50, 40) tu dois utiliser les 3 tableaux redArray, greenArray, blueArray, avec les valeurs suivantes:
greenArray[20]=50
blueArray[30]=40
J'imagine que ta palette de couleur est limitée, donc que plusieurs couleurs de l'image d'origine prendront au final la même couleur. Par exemple si tous les pixels dont R=9,10 ou 11, V=19,20,21 et B=29,30,31 doivnet devenir (10,20,30) il faudra:
redArray[10]=10
redArray[11]=10
greenArray[19]=20
greenArray[20]=20
greenArray[21]=20
blueArray[29]=30
blueArray[30]=30
blueArray[31]=30
Bon, j'espère que je ne m'avance pas trop, j'ai eu la flemme de vérifier que je comprends bien cette fonction

Ça me semble donc tout à fait possible de faire ce que tu veux avec paletteMap, par contre si tu as pas mal de couleurs dans ta palette Ça va peut-être être fastidieux de remplir les tableaux. Où alors trouver un moyen de le faire en le programmant plutôt qu'à la main...
#3
Posté 29 November 2012 - 06:29 AM
Désolé pour hier soit je n'ai pas eu le temps de regarder et donc répondre au poste,
Comme toujours merci de ta réponse.
Donc si j'ai bien compris c'est ce que je pensais plus ou moins... mais je dois faire 3ligne pour chaque couleur ? (une Red une Green un Blue)?
Je ne peux pas simplement faire comme ceci :
redArray= [valeur R de la couleur 1, valeur R de la couleur 2 etc ];
greenArray = [valeur G de la couleur 1, valeur G de la couleur 2 etc];
blue Array = [valeur B de la couleur 1, valeur B de la couleur 2 etc];
Voila ce sera ma question du matin (:
#4
Posté 29 November 2012 - 10:25 AM
Citation
en faite c'est la même chose
faire
tab = [1,2,3];
ou
tab[0] = 1;
tab[1] = 2;
tab[2] = 3;
est la meme chose
a+
ps: je suis pas sure d'avoir compris la question

#5
Posté 29 November 2012 - 10:29 AM
var a:Array = new Array();
a[0] = 10;
a[1] = 20;
a[2] = 30;
[edit] Moi je viens de me faire griller par paodao. Salut paodao

#6
Posté 29 November 2012 - 10:34 AM

#7
Posté 29 November 2012 - 10:36 AM
Moi, je penserais que palettemap n'est pas adapté pour coloriser une image avec une palette.
Palettemap est plutôt adaptée aux corrections de contraste, luminosité, par ce qu'il travaille couche par couche. Il ne permet pas de travailelr par sélection d'une couleur via ses 3 couches.
Un exemple de cas simple pour essayer de montrer l'impossibilité du truc :
- tu as 4 couleurs dans ton image (sur le principe [r,v,b])
[20,20,00], [30,30,00],[00,20,20],[00,30,30]
- tu voudrais passer 1 et 2 à [20,20,00] et 3 et 4 à [00,30,30]
- tu ne peux pas modifier la valeur v parfois vers 20 et parfois vers 30 avec palettemap.
Peut être une solution du côté de threshold, mais je ne suis pas sûr…
Passer pixel par pixel, mais ça sera long… (tout dépend de l'usage)/
#8
Posté 29 November 2012 - 10:50 AM
@paodao et lilive : merci il me semblait bien que se serait plus simple ainsi (étant donné que je possède 256 couleur)...
@dIdIer : pour le threshold il me semblait qu'il modifier tous sur une simple couleur... c'est pourquoi je suis partie sur le palettemap()
Et donc pour répondre à ta question de l'usage :
je possède une palette de 256 couleur pour laquelle j'aimerais l'affecter à n'importe qu'elle image importer dans l'application.
Il me semblait justement que palettemap() permet un "adressage" de couleur comme si par exemple : "toi qui est bleu je n'est pas ta couleur mais ta couleur se rapproche de ce bleu là donc hop je te change!
Donc se serait quelle fonction la mieux ? palettemap ou threshold ? (il se peux que j'avais pas compris cette dernière fonction ^^)
Encore merci pour vos réponse !
#9
Posté 29 November 2012 - 11:13 AM
Un jaune, composé de rouge et de vert sera mécaniquement influencé par les modifications apportées aux canaux rouge et vert.
La seule possibilité que je vois avec paletteMap va dans l'autre sens.
C'est de créer des seuils : 6 par canal, par exemple. Et ce sont ces seuils qui t'imposeront une palette.
La méthode threshold permet de remplacer des couleurs arvb par une autre couleur arvb SI elles passent un test logique. Ça, Ça pourrait permettre d'appliquer une palette de couleurs.
Mais le test logique est assez simple, je crois (je ne l'ai pas beaucoup utilisée cette fonction) et il faut avoir un bon niveau pour jongler avec les opérations binaires pour créer des masques par canaux…
#10
Posté 29 November 2012 - 11:17 AM
Citation
Le principe à disposition :
Citation
- Si ((pixelValue & mask) operation (threshold & mask)), définissez le pixel sur color.
- Dans le cas contraire, si copySource == true, réglez le pixel sur la valeur de pixel correspondante dans sourceBitmap.
#11
Posté 29 November 2012 - 11:17 AM
Et donc le test logique consiste en quoi? l'utilisation d'un bytearray?
désolé si je suis confus dans mes question mais là tu viens de me perdre

#12
Posté 29 November 2012 - 11:18 AM
Pourquoi l'utilisation de mask?
#13
Posté 29 November 2012 - 11:35 AM
Si ça ne te parle pas, tu peux oublier. C'est très complexe. J'ai beaucoup de mal avec ça et je ne me sens pas de pousser plus loin mes recherches. A chaque fois ça a été un chronophage monstrueux (à moins que quelqu'un de plus pointu soit dispo ?)
paletteMap et treshold sont des routines très rapides mais pas très souples, amha.
Si tu n'as pas besoin d'une rapidité foudroyante, je pense que tu devrais plutôt faire une boucle pixel à pixel, avec des tests plus traditionnels. Et au besoin, on pourra t'aider à l'optimiser.
#14
Posté 29 November 2012 - 11:46 AM
Je vais me renseigner et voir l'utilisation du threshold de plus près !
Mais pour ta boucle pixel à pixel en français sa donnerai ça ? :
Pour le pixel n°1 si ça couleur est différente de la couleur disponible dans la palette alors changer ça couleur en fonction d'une couleur plus proche...
Si c'est bien ça, je ferais également un petit test avec cette méthode...
Encore merci du temps que tu m'accordes !
#15
Posté 29 November 2012 - 11:57 AM
pour les mask c'est pas tres compliqué en faite (mais je suis pas sure d'avoir tout compris)
cela sert à ciblier les canaux que tu veux utiliser pour le test
par exemple tu as la couleur
aabbcc
tu met le mask
ffffff
cela va utiliser tous les canaux
maintenant si tu utilise le mask
ff00ff
cela ne va pas utiliser le canal vert
dans beaucoup de cas tu peux utiliser le mask 0xffffffff
a+
#16
Posté 29 November 2012 - 11:58 AM
Pour la boucle traditionnelle, je ferais sans doute quelque chose comme ça :
couleur = couleur dans l''image
r = canal r de la couleur
v = canal v de la couleur
b = canal b de la couleur
au_plus_proche = 255*3;
pour chaque p_couleur = couleur de la palette {
p_r = valeur absolue de la diffférence entre r et canal r de p_couleur
p_v = valeur absolue de la diffférence entre v et canal v de p_couleur
p_b = valeur absolue de la diffférence entre b et canal b de p_couleur
différence = p_r + p_v + p_b
si différence inférieure à au_plus_proche, je mémorise p_couleur
}
j''applique la valeur p_couleur mémorisée au pixel (x,y)
}
Ensuite, il y aura beaucoup d'optimisations possibles si c'est trop lent, mais ça te permettra déjà de voir si le rendu est celui que tu attends.
#17
Posté 29 November 2012 - 12:47 PM

Effectivement paletteMap ne semble pas un bon candidat pour faire ça.
Heureusement que Dldler est passé par là (je l'attendais d'ailleurs, sur un tel sujet

Un autre essai possible serait peut-être d'utiliser une formule légèrement différente pour la différence?
couleur = couleur dans l''image
r = canal r de la couleur
v = canal v de la couleur
b = canal b de la couleur
au_plus_proche = 255*3;
pour chaque p_couleur = couleur de la palette {
p_r = soustraction entre r et canal r de p_couleur
p_v = soustraction entre v et canal v de p_couleur
p_b = soustraction entre b et canal b de p_couleur
différence = Math.sqrt( p_r * p_r + p_v * p_v + p_b * p_b )
si différence inférieure à au_plus_proche, je mémorise p_couleur
}
j''applique la valeur p_couleur mémorisée au pixel (x,y)
}
Kainry, pour faire cela en actionscript tu auras besoin de ceci, je te le dis car je ne sais pas si tu connais:
var c:uint = unBitmapData.getPixel(x,y); // récupére la couleur du pixel x,y
var r:int = c >> 16; // valeur du canal rouge de c
var v:int = (c >> 8) & 0xFF; // valeur du canal vert de c
var b:int = c & 0xFF; // valeur du canal bleu de c
unBitmapData.setPixel(x, y, 0xAA8844); // Peint le pixel x,y avec la couleur 0xAA8844
#18
Posté 29 November 2012 - 12:58 PM
Me voila plus éclairer dans ma recherche et aide à solution.
Je vais tester ça dans l'après midi si j'en ai le temps je vous tiendrais tous au courant !
@lilive par contre pourrait tu m'éclairer sur le 16, et 8 qui tu à utiliser? pourquoi ces deux nombres? les numéros des bytes correspondant à la couleur? genre le bleu de 0 à 8, le vert de 9 à 16, le rouge de 17 à 24 ? (si j'ai bien compris ^^)
Encore merci à vous 3 !
#19
Posté 29 November 2012 - 13:06 PM
Kainry, le 29 November 2012 - 12:58 PM, dit :
#20
Posté 29 November 2012 - 13:10 PM
#21
Posté 29 November 2012 - 13:13 PM

Si besoin, un article que j'ai trouvé qui peut donner des idées: http://blog.soulwire...-colour-palette
#22
Posté 29 November 2012 - 21:37 PM
#23
Posté 30 November 2012 - 09:50 AM
Pour tester, il faut copier le code dans l'image 1 d'un fichier Flash.
Dans ce fichier Flash, il faut importer une image dans la bibliothèque et la partager pour ActionScript sous le nom Test.
Ne pas mettre une image trop grande, le code est lent.
J'ai créé une palette par le code. Comme elle a une logique progressive, on pourrait optimiser l'algorithme en calculant la valeur par canal plutôt que de comparer avec les couleurs de la palette, mais ça ne fonctionnera pas si ta palette est aléatoire ou provient d'une autre source d'image… A toi de voir.
J'ai commenté autant que j'ai pu, mais je n'aurai sans doute pas le temps de répondre aux questions.
Peut-être que d'autres pourront prendre le relais.
// On prépare le bitmapdata, les variables nécessaires au calcul
// et on affiche le bitmap
var bm:BitmapData = new Test(0,0);
var largeur:int = bm.width;
var hauteur:int = bm.height;
addChild(new Bitmap(bm));
// Plein de variables nécessaires aux calculs.
// Déclarées ici pour gagner du temps à l'exécution
var _rvb:uint; // Servira à stocker une couleur
var _drvb:uint; // Servira à stocker une différence entre 2 couleurs
var _rvb_proche:uint; // Servira a stocker la couleur la plus proche
var _drvb_proche:uint; // Servira à stocker la plus petite différence
var _r:uint,_v:uint,_b:uint; // Servira à stocker la valeur des canaux RVB
var _dr:int,_dv:int,_db:int; // Servira à stocker la différence par canal RVB
var i:int,j:int,k:int; // compteurs pour les boucles
// Pour la création d'une palette d'exemple
var ecart_couleur:int = 44; // Ecrat entre chaque teinte pour chaque canal
var nbre_couleurs:int; // Nombre de couleurs dans la palette
nbre_couleurs = 256 / ecart_couleur + 1;// nbre couleurs par couche
nbre_couleurs = nbre_couleurs * nbre_couleurs * nbre_couleurs + 1;// nbre couleurs total
var palette:Vector.<uint>;
palette = new Vector.<uint>(nbre_couleurs,true);
// Pour éviter de refaire des calculs,
// on stocke les décompositions par canal des couleurs de la palette
var p_r:Vector.<uint>;
var p_v:Vector.<uint>;
var p_b:Vector.<uint>;
p_r = new Vector.<uint>(nbre_couleurs,true);
p_v = new Vector.<uint>(nbre_couleurs,true);
p_b = new Vector.<uint>(nbre_couleurs,true);
// Fabrication d'une palette par intervalles
// On en profite pour stocker les valeurs r, v, b
// afin de limiter les calculs
i = 0;
for (_r=0; _r<256; _r+=ecart_couleur)
{
for (_v=0; _v<256; _v+=ecart_couleur)
{
for (_b=0; _b<256; _b+=ecart_couleur)
{
_rvb=_r<<16|_v<<8|_b;
palette[i]=_rvb|0xFF000000;
p_r[i]=_r;
p_v[i]=_v;
p_b[i++]=_b;
}
}
}
// On ajoute du blanc à la palette
palette[i]=0xFFFFFFFF;
p_r[i]=p_v[i]=p_b[i]=0xFF;
/*
* CODE PRINCIPAL
*/
bm.lock(); // Accélère l'accès au bm
// On parcourre le bitmapdata
for (i=0; i<largeur; i++)
{
for (j=0; j<hauteur; j++)
{
_rvb=bm.getPixel(i,j); // La couleur au point (i,j)
// On ne travaille pas les couleurs présentes dans la palette
if (palette.indexOf(_rvb)!=-1) break;
// On décompose la couleur
_r=_rvb>>16&0xFF;
_v=_rvb>>08&0xFF;
_b=_rvb>>00&0xFF;
// Valeurs de départ de la plus petite différence
// et de la couleur la plus proche
_rvb_proche=0x000000;
_drvb_proche=uint.MAX_VALUE;
// Pour chaque couleur de la palette, on calcule les différences par canaux,
for (k=0; k<nbre_couleurs; k++)
{
_dr=_r>p_r[k] ? _r-p_r[k] : p_r[k]-_r;
_dv=_v>p_v[k] ? _v-p_v[k] : p_v[k]-_v;
_db=_b>p_b[k] ? _b-p_b[k] : p_b[k]-_b;
_drvb=_dr+_dv+_db;
// si la différence est inférieure, on stocke les valeurs trouvées
if (_drvb<_drvb_proche)
{
_drvb_proche=_drvb;
_rvb_proche=palette[k];
}
}
// On applique la couleur trouvée au pixel (i,j)
bm.setPixel(i,j,_rvb_proche);
}
}
bm.unlock(); // Libère l'affichage du bm
#24
Posté 30 November 2012 - 10:18 AM
Je m'y penche cette après-midi mais après une lecture rapide les commentaires m'aideront à tous comprendre.
Encore merci
#25
Posté 01 December 2012 - 10:26 AM
J'ai mis 3 slider qui permettent de donner un priorité plus ou moins grande aux valeurs HSL. On peut donc privilégier la ressemblance au niveau de la teinte, de la saturation, ou de la luminosité.
Voici ce que ça donne. Je suis un peu déçu, ça n'améliore pas franchement il me semble. Peut-être qu'avec une autre image et une autre palette le résultat serait plus probant?
C'est largement plus lent à l'exécution qu'en mode RVB, c'est pour cela que j'ai mis une petite case à cocher pour travailler sur une version basse résolution de l'image.
En mode RVB:
- Afficher le SWF -

En mode HSL:
- Afficher le SWF -

Comparaison:

Sources:

#26
Posté 01 December 2012 - 14:29 PM
Alors j'ai cherché avec d'autres palettes de couleurs pour voir, me disant que certaines palettes seraient peut-être optimisées pour une comparaison en HSL.
Et comme je n'étais pas encore convaincu, j'ai codé un outils de comparaison des 2 méthodes, sur différentes images, avec différentes palettes.
Le voici.
Je suis toujours aussi mitigé sur la pertinence d'utiliser le HSL plutôt que le RVB

Mais ton sujet m'a bien intéressé comme tu vois Kainry!
[edit] Hum, le HSL peut être pas mal quand même... Je viens d'essayer avec la palette de Dldler, le curseur H à 0.1, le S encore plus bas, et le L à 1, et j'ai trouvé ça mieux que le RVB. dites-moi ce que vous en pensez si vous voulez

Fichier(s) joint(s)
#27
Posté 01 December 2012 - 20:14 PM

J'ai ajouté une comparaison en mode HSV.
J'ai aussi essayé de définir une autre palette, mais elle est nulle.
- Afficher le SWF -


#28
Posté 03 December 2012 - 09:10 AM
Désolé de te laisser jouer tout seul. Je ne peux plus faire de Flash chez moi. Même pas acceder aux forums… :-(
Du coup, il me reste les pauses au boulot et le midi en semaine pour participer.
La comparaison est en effet assez difficile, surtout parce que les images sont très petites.
De mon côté, j'ai optimisé et accéléré les calculs, mais sans doute en perdant encore un peu de qualité. Par contre, ça devrait t'aider à faire des tests viables sur des images plus grandes.
Et puis c'est un bon exemple de la façon d'utiliser le threshold pour limiter les calculs.
Je nettoie le code et je commente avant de poster. Je vous dépose ça à 14h si c'est prêt.
#29
Posté 03 December 2012 - 14:00 PM
Le code est assez ésotérique, même commenté.
Une 'certaine' maîtrise du binaire est recommandée (pour comprendre ce qui se passe).
Sinon, vous pouvez l'utiliser sans forcément tout comprendre, en modifiant la palette selon vos envies (voir les versions de lilive et je regarde à construire une palette 6x6x4 via du code)
Et vous pouvez changer la qualité de la conversion en modifiant la propriété 'arrondi'.
Elle correspond a la suppression du nombre de bits correspondants.
Soit :
- arrondi 4 : les bits 1,2,3,4 en partant de la droite ne sont pas pris en compte
La valeur peut donc aller de 1 à 7 en théorie.
Dans la pratique on est limité par le temps de traitement selon la puissance de la machine.
Tout ça accélère les calculs et je peux maintenant traiter une image 800x600 sur mon vieux poste en arrondi 5
Je pourrai donner quelques précisions s'il y a des questions.
var _r:uint,_v:uint,_b:uint;// Compteurs pour les boucles RVB
// On prépare le bitmapdata et on affiche le bitmap
var bm:BitmapData = new Test(0,0);
var rectangle:Rectangle = bm.rect;
var OO:Point = new Point();
addChild(new Bitmap(bm));
// Gestion de la précision au niveau du bit : on prépare les masques binaires
var arrondi:uint = 5;// Ici, les 5 bits de droite (faibles) seront inutilisés et donc masqués lors des calculs
var _arrondi:uint = 1 << arrondi;
var masque_arrondi:uint = 0xFF << 24 | (_arrondi - 1) << 16 | (_arrondi - 1) << 8 | (_arrondi - 1);// Les bits arvb utiles
masque_arrondi = ~ masque_arrondi; // Le masque des inutiles
// Plein de variables nécessaires au calculs des différences
// Déclarées ici pour gagner du temps à l'exécution
var _rvb:uint;// Servira à stocker une couleur
var _rvb_proche:uint;// Servira a stocker la couleur la plus proche
var _difference_rvb:uint;// Servira à stocker une différence entre 2 couleurs
var _difference_rvb_proche:uint;// Servira à stocker la plus petite différence
var _difference_r:Vector.<uint>;// Servira a stocker les pré_calculs de différences
var _difference_v:Vector.<uint>;// Servira a stocker les pré_calculs de différences
var _difference_b:Vector.<uint>;// Servira a stocker les pré_calculs de différences
// Création d'une palette d'exemple
var palette:Vector.<uint>;// Vecteur des valeurs uint des couleurs de la palette
var nombre_de__couleurs:int;// Nombre de couleurs dans la palette
var ecart_couleur:int = 44;// Ecart entre chaque teinte pour chaque canal
nombre_de__couleurs = 0x100 / ecart_couleur + 1;// nbre couleurs par couche
nombre_de__couleurs = nombre_de__couleurs * nombre_de__couleurs * nombre_de__couleurs + 1;// nbre couleurs total
palette = new Vector.<uint>(nombre_de__couleurs,true);
// On fabrique la palette par ajout de l'écart sur les canaux rvb
i = 0;
for (_r=0; _r<0x100; _r+=ecart_couleur)
{
for (_v=0; _v<0x100; _v+=ecart_couleur)
{
for (_b=0; _b<0x100; _b+=ecart_couleur)
{
palette[i++]=0xFF<<24|_r<<16|_v<<8|_b;
}
}
}
// On impose le blanc dans la palette
palette[i]=0xFFFFFFFF;
// Pour éviter de refaire des calculs de différences,
// on les stocke dans un tableau 2 dimensions permettant d'obtenir :
// differences_pour[a][b] = valeur absolue de la différerence entre a et b
// (a et b pouvant varier de 0 à 0xFF)
var differences_pour:Vector.<Vector.<uint>>=new Vector.<Vector.<uint>>(0x100,true);
for (i=0; i<0x100; i++)
{
differences_pour[i]=new Vector.<uint>(0x100,true);
for (j=0; j<0x100; j++)
{
differences_pour[i][j]=i<j?j-i:i-j;
}
}
/*
* code principal
*/
// Le principe est de parcourir la gamme de toutes les couleurs possibles,
// mais en utilisant l'arrondi pour incrémenter les canaux rvb
// L'arrondi est masqué par le threshold, ce qui lui permet de traiter
// en un seul passage toutes les couleurs avec une précision au bits non masqués par l'arrondi
// NB : ça fonctionne parce que l'arrondi est un nombre ne comprenant que des 1 en binaire !
for (_r=0; _r<0x100; _r+=_arrondi)
{
// On charge les différences précalculées pour r
_difference_r=differences_pour[_r];
for (_v=0; _v<0x100; _v+=_arrondi)
{
// On charge les différences précalculées pour v
_difference_v=differences_pour[_v];
for (_b=0; _b<0x100; _b+=_arrondi)
{
// On charge les différences précalculées pour b
_difference_b=differences_pour[_b];
// Valeurs de départ de la plus petite différence et de la couleur la plus proche
_rvb_proche = _difference_rvb_proche = uint.MAX_VALUE;
// Pour chaque couleur de la palette, on calcule les différences par canaux,
// si la différence est inférieure, on stocke les valeurs trouvées
for each (_rvb in palette)
{
_difference_rvb=_difference_r[_rvb>>16&0xFF]+_difference_v[_rvb>>8&0xFF]+_difference_b[_rvb&0xFF];
if (_difference_rvb<_difference_rvb_proche)
{
_difference_rvb_proche=_difference_rvb;
_rvb_proche=_rvb;
}
}
// On applique la couleur à tout ce qui est proche, en masquant les bits inutiles
bm.threshold(bm,rectangle,OO,"==",_r<<16|_v<<8|_b,_rvb_proche,masque_arrondi);
}
}
}
bm.unlock();// Libère l'affichage du bm
#30
Posté 03 December 2012 - 20:19 PM

Bonne idée que tu as eue.
Fais-je erreur en conjecturant que son inconvénient est qu'on ne peut pas bien focaliser la précision sur des endroits de la gamme de couleur? (par exemple on ne peut décider d'avoir une palette plus fournie pour les couleurs saturées?)
Il faudrait l'inclure à mon application de comparaison des méthodes.
Si j'ai bien compris le projet de Kainry, ce n'est pas grave si les images ne sont pas grandes, puisqu'il se dirige vers du graphisme pixel art (cf ici), d'où mon parti pris de réduire les images puis les re-agrandir pour obtenir la pixelisation.
Et de mon côté j'ai eu une autre idée pour simplement réduire les couleurs à une palette 8x8x4:
var ct:ColorTransform = new ColorTransform(8 / 256, 8 / 256, 4 / 256, 1);
destBD.draw(sourceBD, null, ct);
// les canaux de couleurs sont maintenant dans l'intervale [0..7][0..7][0..3]
ct = new ColorTransform(255 / 7, 255 / 7, 255 / 3, 1);
destBD.draw(destBD, null, ct);
// les canaux de couleurs repassent dans l'intervale [0..255][0..255][0..128]
Du coup c'est très rapide. Mais on ne peux absolument rien paramétrer, la palette de sortie est imposée.
Le hic c'est que ça ne marche pas comme ça, tout le bleu disparait, ça doit être une incompréhension de ma part de la mécanique interne du ColorTransform.
Je m'en suis sorti comme ça:
var ct:ColorTransform = new ColorTransform(8 / 256, 8 / 256, 4 / 256, 1);
destBD.draw(sourceBD, null, ct);
// les canaux de couleurs sont maintenant dans l'intervale [0..7][0..7][0..3]
ct = new ColorTransform(255.01 / 7, 255.01 / 7, 128.01 / 3, 1);
destBD.draw(destBD, null, ct);
// les canaux de couleurs sont maintenant dans l'intervale [0..255][0..255][0..128]
ct = new ColorTransform(1, 1, 255.01 / 128, 1);
destBD.draw(destBD, null, ct);
// les canaux de couleurs repassent dans l'intervale [0..255][0..255][0..255]
Voici mon application de test incluant ce nouveau mode de calcul:
- Afficher le SWF -


#31
Posté 04 December 2012 - 14:25 PM
var i:Number = 0;
var r:Number,v:Number,b:Number;
var intervalle_couleur:Number = 0x100/7; // NB : 8 couleurs =7 intervalles
for (r=0; r<0x100; r+=intervalle_couleur)
{
for (v=0; v<0x100; v+=intervalle_couleur)
{
for (b=0; b<0x100; b+=intervalle_couleur+intervalle_couleur)
{
palette[i++]=r<<16|v<<8|b;
}
}
}
// Affichage
i=0;
for each (var rvb:uint in palette)
{
graphics.beginFill(rvb);
graphics.drawRect(int(i/8)*10,i++%8*10,8,8);
graphics.endFill();
}
Pour le reste, je n'ai pas trop le temps, désolé.
Mais bubulle m'a l'air très bien :-)
Fichier(s) joint(s)
#32
Posté 04 December 2012 - 19:40 PM
Je ne crois pas que tu l'aies vu, mais dans mon code j'ai fait aussi une 8x8x4.
Je m'y suis pris comme ça:
var r:int, v:int, b:int;
i = 0;
for (var rr:int = 0; rr < 8; rr ++) {
for (var vv:int = 0; vv < 8; vv ++) {
for (var bb:int = 0; bb < 4; bb ++) {
r = Math.round(rr / 7 * 255);
v = Math.round(vv / 7 * 255);
b = Math.round(bb / 3 * 255);
rvb = r << 16 | v << 8 | b;
setPaletteColor(rvb, i);
i++;
}
}
}
Ton bleu prend les valeurs: 0, 73, 146, 219
Le mien les valeurs: 0, 85, 170, 255
Je viens de lire que l'opérateur de décalage converti bien le nombre en int avant de faire l'opération, donc la différence ne vient pas de là.
#33
Posté 05 December 2012 - 09:58 AM

La différence vient de la :
// NB : 8 couleurs =7 intervalles
Alors évidemment, on ne peut pas calculer via le double.
Puisqu'on a 4 couleurs = 3 intervalles…
Du coup, je me rends compte que mon intervalle n'était pas tout à fait juste non plus.
Voilà les 2 corrections :
var i:Number = 0;
var r:Number,v:Number,b:Number;
var intervalle_RV:Number = 0xFF/7; // NB : 8 couleurs = 7 intervalles
var intervalle_B:Number = 0xFF/3; // NB : 4 couleurs = 3 intervalles
for ( r = 0; r < 0x100; r += intervalle_RV )
{
for ( v = 0; v < 0x100; v += intervalle_RV )
{
for ( b = 0; b < 0x100; b += intervalle_B )
{
palette[i++]=r<<16|v<<8|b;
}
}
}
trace(palette[255].toString(16));
#34
Posté 05 December 2012 - 10:20 AM
Désolé je ne commente pas trop ce qui ce passe ici mais je suis !
Je suis sur un autre problème en attendant mais je vois que vous vous amusez bien avec ce sujet

Encore merci pour votre aide,
Je risque de vous posez des questions quand je m'y pencherais sérieusement,
Et je vous tiendrais au courant quand j'en aurais fini avec tous ça pour que vous voyez le rendu final du projet.
Kainry.
#35
Posté 05 December 2012 - 18:52 PM
Kainry, le 05 December 2012 - 10:20 AM, dit :

Kainry, le 05 December 2012 - 10:20 AM, dit :


Kainry, le 05 December 2012 - 10:20 AM, dit :
1 utilisateur(s) li(sen)t ce sujet
0 membre(s), 1 invité(s), 0 utilisateur(s) anonyme(s)