Aide - Recherche - Membres - Calendrier
Version complète : Algorithme de transparence d'une image sur une autre ...
Les Forums de PalmAttitude.org > GENERAL PalmOS > Développement sous PalmOS
Khertan
Bah voila tout est dans le titre...

L'un de vous aurez un algo de dessin en transparence d'une image sur une autre ... (de la vrai transparence ... pas un mask, une couche alpha).
Schtunks
Peut-être Eric Quagliozzi peut t'aider sur ce sujet. Il est féru d'effets graphique en ARMlets ! Sur son site il y a ça et c'est free ! sourire.gif
Khertan
Ah bah oui ... il y a un truc d'alpha blending ... le probleme ... c'est que ce n'est pas open source ... donc j'ai pas l'algo sourire.gif
Schtunks
Bah, peut-être qu'Eric, qui passe de temps en temps, pourra t'expliquer comment ça marche... anim_sorry.gif
poolpy
CITATION(Khertan @ 18/04/2007 à 18:06 ) *
Bah voila tout est dans le titre...

L'un de vous aurez un algo de dessin en transparence d'une image sur une autre ... (de la vrai transparence ... pas un mask, une couche alpha).


Ca te convient pas la somme pondérée des composantes R G B des deux images ? Si tes couleurs sont des entiers 8 bits, avec alpha constante entre 0 et 256 :

destination.r = (alpha * source.r + (256-alpha) * destination.r) >> 8
destination.g = (alpha * source.g + (256-alpha) * destination.g) >> 8
destination.b = (alpha * source.b + (256-alpha) * destination.b) >> 8

Tu peux aussi avoir une image en niveaux de gris qui te donne la transparence de chaque pixel, auquel cas tu utilises en chaque point sa valeur pour alpha.

Pour le 16 bits, il faut faire un peu de gymnastique des bits pour extraire les valeurs RGB, et du coup les intervalles ne sont plus sur 0..255 mais sur respectivement 0..32, 0..64, 0..32 pour le rouge, vert et bleu (5:6:5).

Pour le 8 bits, c'est plus galère parce que tu dois convertir les indices de couleurs en valeurs RGB, et surtout, une fois que tu trouves la couleur cible, trouver l'indice de la couleur qui s'en rapproche le plus... Si tu peux te payer le luxe de réserver 64ko de RAM, tu peux te faire un cache que tu remplis au fur et à mesure pour éviter d'avoir à faire à chaque pixel les opérations :
- De conversion des des indices de couleurs dans les images source (i) et destination (j) en leurs valeurs RGB.
- Le compositage des deux couleurs.
- La recherche dans la palette de la couleur la plus proche (d'indice k).
Une fois que tu l'as fait, tu stockes dans ton cache en [i][j] la valeur k. Et avant de faire la conversion ou le compositage, tu cherches si en [i][j] il y a quelque chose dans ton cache (avec la convention 0 = entrée non remplie)... C'est surtout efficace si les deux images ont beaucoup de pixels de couleurs identiques (dessins au trait).
quagliozzi
CITATION(Khertan @ 18/04/2007 à 20:52 ) *
Ah bah oui ... il y a un truc d'alpha blending ... le probleme ... c'est que ce n'est pas open source ... donc j'ai pas l'algo sourire.gif


Je viens juste de découvrir ton post!!! désolé icon_bla.gif

Oui, il n'est pas "open source", mais bon, je peux faire une exception.
L'algo utilisé est exactement celui décrit par Poolpy, si tu veux la source, un MP.
Pour l'extraction de la couleur réultante en 8 bits depuis la palette de couleur, j'utilise un algo maison, très rapide mais pas très rigoureux.
Le rendu final n'en souffre pas plus que cela, d'autant plus que très franchement, l'alphablending en 8 bits je trouve cela plutôt moche.

D'une façon générale, si tu veux connaître les algo graphiques, il y a des tonnes de très bonnes descriptions et docs sur le net, et de très bon livres (le mieux est de le faire soi même, c'est plus formateur). J'ai par exemple trouvé de très bonnes explications dans un livre sur Direct3D. A la base, utilisé et destiné à la programmation 3D sous windows, mais l'auteur propose de nombreux chapitres sur les explications physiques, la modélisation mathématique et souvent les algo rapides associés.

A+
Eric.
2P2M
Une idée pour dessiner un rectangle transparent par-dessus une image comme dans les 2 exemples joints ?
D2P
CITATION(2P2M @ 24/01/2008 à 11:24 ) *
Une idée pour dessiner un rectangle transparent par-dessus une image comme dans les 2 exemples joints ?

Voila bien longtemps que quagliozzi n'est pas passé par ici anim_sorry.gif Je te conseille de lui envoyer un mail anim_wink.gif
poolpy
CITATION(2P2M @ 24/01/2008 à 11:24 ) *
Une idée pour dessiner un rectangle transparent par-dessus une image comme dans les 2 exemples joints ?


Regarde mon post au dessus.

Destination: image de départ
Source: rectangle noir
Alpha: indice de transparence (sur 256), ici 128 par exemple
2P2M
Mon problème est que je n'arrive pas à extraire le RGB de ma bitmap 16 bits icon_cry.gif
Voici mon code (simplifié) :

#define ByteSwap16( x ) ( UInt16 )( ( ( ( UInt16 )( x ) << 8 ) | ( ( UInt16 )( x ) >> 8 ) ) )
#define MASK_R ( 0x1F << 11 )
#define MASK_G ( 0x3F << 5 )
#define MASK_B 0x1F

void AlphaBitmap
(
Int16 width,
Int16 height,
UInt16* dest,
UInt16 destRowBytes,
UInt16* src,
UInt16 srcRowBytes
)
{
UInt16* inPtr;
UInt16* outPtr;
UInt8 fr,fg,fb,tr,tg,tb;

if ( width == 0 || height == 0 )
return;

inPtr = src;
outPtr = dest;

for (i=0;i<height;i++)
{
for (j=0;j<width;j++)
{
UInt16 s;

s = ByteSwap16( *inPtr );
fr = s & MASK_R;
fg = s & MASK_G;
fb = s & MASK_B;
s = ByteSwap16( *outPtr );
tr = s & MASK_R;
tg = s & MASK_G;
tb = s & MASK_B;

*outPtr =((128 * fr + (256-128) * tr) >> 8 |
(128 * fg + (256-128) * tg) >> 8 |
(128 * fb + (256-128) * tb) >> 8) ;

inPtr ++;
outPtr ++;
}
}
}

Quand je trace mes fr,fg,fb,tr,tg,tb, je n'ai pas les bonnes valeurs de rouge, vert et bleu.
Je me doute que c'est dans le shift que ça coince, mais je ne trouve pas la solution !
Je tiens à signaler que les données dans les bitmaps avant l'appel sont bonnes... JE CRAQUE !
poolpy
Déjà il ne suffit pas d'appliquer un masque binaire, il faut aussi redécaler les bits à droite. Dans ton cas, >> 11 pour R, >> 5 pour G (à condition que ce soit R5G6B5 évidemment) si tu veux avoir les valeurs de base (sur 0-31 pour R et B, 0-63 pour G).

Ma formule traitait le cas où R, G et B étaient représentés par le range 0-255. Donc il faut adapter un peu: utilise >> 8 pour R, >> 3 pour G et << 3 pour B si tu veux retrouver des valeurs dans 0-255.

Un autre problème: fr,tr etc sont tous des UInt8 dans tout code. Y a aucune chance que ça marche, parce que tu vas faire des multiplications dessus qui vont causer des débordements de capacité. Ou tu les déclares en UInt16, ou tu les castes en UInt16 quand tu fais des calculs avec.

Enfin, une fois que tu as les composantes R, G, B finales, il faut reconstituer un UInt16 au format R5G6B5, ce que tu as oublié de faire.

Donc là, tu masques les 5 bits de poids fort de R et tu les décales de 8 à gauche, tu masques les 6 bits de poids fort de G et tu les décales de 3 à gauche, tu masques les 5 bits de poids fort de B et tu les décales de 2 à droite. Et le | du tout te donne un UInt16 qui est la bonne couleur.
Ceci est une version "bas débit" de notre forum. Pour voir la version complète avec plus d'information, la mise en page et les images, veuillez cliquer ici.
Invision Power Board © 2001-2008 Invision Power Services, Inc.