algo de conversion d image 16 bits en 24 bits

algo de conversion d image 16 bits en 24 bits - Algo - Programmation

Marsh Posté le 20-05-2003 à 09:13:20    

salut,
 
j ai une image en 16 bits de taille 2*largeur*hauteur, je voudrais la convertir en 24 bits mais je ne trouve pas la formule , quelqu un la connait ? (cherché  sur google mais rien du tout)
 
merci

Reply

Marsh Posté le 20-05-2003 à 09:13:20   

Reply

Marsh Posté le 20-05-2003 à 09:15:57    

Code :
  1. unsigned int convert(unsigned short src)
  2. {
  3. unsigned int r = (src & 0xF800) >> 11;
  4. unsigned int g =(src & 0x7E0) >> 5;
  5. unsigned int b = (src & 0x1F) ;
  6. r<<=3;
  7. g<<=2;
  8. b<<=3;
  9. return (r<<16) | (g<<8) | b
  10. }


 
 
sous entendant que ton 16bits c'est du R5G6B5
 
va falloir que tu te penches sur le format d'encodage des couleurs et la manipulations de bits
 
le resultat est ici 32bits mais bon, 24 ou 32, c kif kif, l'algo change pas, juste balance ton resultat dans une structure de 24 bits ou un tableau de char au lieu de mon unsigned int final


Message édité par chrisbk le 20-05-2003 à 09:19:52
Reply

Marsh Posté le 20-05-2003 à 09:26:35    

merci bien, c effectivement du 565 (le plus classique) et je stocke ca dans un tableau de char.
 
:jap:

Reply

Marsh Posté le 20-05-2003 à 09:55:50    

hum, ca fonctionne mais mon cyan apparait jaune ... je crois que l algo inverse que j ai est faux :
(r,g,b)->(byte1,byte2)  "/" -> c est le OU logique car chui sur un mac et c la merde je trouve pas la barre verticale

Code :
  1. byte1 = (g<<3 & 0xE0) / r >>3;
  2. byte2 = (b & 0xF8) / g >> 5;


 
me suis je trompé ou c bon?

Reply

Marsh Posté le 20-05-2003 à 10:02:30    

xilebo a écrit :

hum, ca fonctionne mais mon cyan apparait jaune ... je crois que l algo inverse que j ai est faux :
(r,g,b)->(byte1,byte2)  "/" -> c est le OU logique car chui sur un mac et c la merde je trouve pas la barre verticale

Code :
  1. byte1 = (g<<3 & 0xE0) / r >>3;
  2. byte2 = (b & 0xF8) / g >> 5;


 
me suis je trompé ou c bon?  


 
heuh c quoi cette histoire de | qui existe pas ? :heink:
tu veux convertir de 24 a 16 ?

Code :
  1. unsigned int r = ((src&0xFF0000)>>19);
  2. unsigned int g = ((src&0xFF00)>>10);
  3. unsigned int b = ((src&0xFF)>>3);
  4. return (unsigned short) (r<<11) | (g<<5) | b;


 
 
 
 
 
 

Reply

Marsh Posté le 20-05-2003 à 10:49:16    

c pas qu il existe pas ... c que je le trouve pas sur l imac :-/  
 
ok remerci a nouveau pour ton algo je vais essayer de ce pas.

Reply

Marsh Posté le 20-05-2003 à 12:25:32    

Algo rapide, mais qui perd pas mal d'infos : le blanc devient du gris clair .. Heureusement que le format n'est pas du 4444 parce que sinon, ca se sentirait bien, comme diff ...
 
L'avantage, c'est qu'il est rapide ...
 
 
Pour ce qui est de la présentation de l'algo, je préfère cette méthode :

Code :
  1. typedef struct _SPixel565 {
  2.   unsigned B : 5;
  3.   unsigned G : 6;
  4.   unsigned R : 5;
  5. } SPixel565;
  6. typedef struct _SPixel888 {
  7.   unsigned short B;
  8.   unsigned short G;
  9.   unsigned short R;
  10. } SPixel888;
  11. unsigned int convert(unsigned short src)
  12. {
  13.   SPixel565 tmp = (SPixel565)src;
  14.   SPixel888 dst;
  15.   dst.R = tmp.R<<3;
  16.   dst.G = tmp.G<<2;
  17.   dst.B = tmp.B<<3;
  18.   return dst;
  19. }


---------------
last.fm
Reply

Marsh Posté le 20-05-2003 à 12:38:06    

theShOcKwAvE a écrit :

Code :
  1. unsigned int convert(unsigned short src)
  2. }




 
repiquer betement les entetes de fonction de ses petits camarades sans prendre le tps de les adapter, c'est mal [:aloy]


Message édité par chrisbk le 20-05-2003 à 12:38:24
Reply

Marsh Posté le 22-05-2003 à 13:41:00    

chrisbk a écrit :


 
repiquer betement les entetes de fonction de ses petits camarades sans prendre le tps de les adapter, c'est mal [:aloy]


 

Code :
  1. typedef struct _SPixel565 {
  2. unsigned B : 5;
  3. unsigned G : 6;
  4. unsigned R : 5;
  5. } SPixel565;
  6. typedef struct _SPixel888 {
  7. unsigned short B;
  8. unsigned short G;
  9. unsigned short R;
  10. } SPixel888;
  11. unsigned int convert(SPixel565) 
  12. SPixel888 dst;
  13. dst.R = src.R<<3;
  14. dst.G = src.G<<2;
  15. dst.B = src.B<<3;
  16. return dst;
  17. }


 
Si tu préfères ... L'avantage, c'est que ca restait transparent pour l'utilisateur de la fct ... (utilité assez réduite, je l'accorde, mais ca évite de caster à chaque appel si il n'utilise pas des images faites à base de SPixel565, ce qui ne m'étonnerait guère ... ;))
 
Edit : Je précis que dans mon post précédent, je voulais surtout mettre l'accent sur la perte de précision : pour chaque couleur, 0 devient 0, ... normal, quoi, mais 11111 deviendra 11111000(0xF8) au lieu de 11111111 (0xFF) pour le R et le B :( (un peu mieux pour le G, mais c'est pas encore le top) Donc si vous trouvez une solution performante pour éviter ce problème, je suis intéressé
 


Message édité par theshockwave le 22-05-2003 à 13:43:46

---------------
last.fm
Reply

Marsh Posté le 22-05-2003 à 13:47:03    

tiens oui j'avais jamais fait gaffe a ca [:mlc]
aucune idee la pour le moment, je me console juste en me disant que les conversion 16->24 on en fait pas ts les jours :D

Reply

Marsh Posté le 22-05-2003 à 13:47:03   

Reply

Marsh Posté le 22-05-2003 à 15:07:31    

Et comme ca :

Code :
  1. dest.R = (src.R << 3) + (src.R >> 2);
  2. dest.G = (src.G << 2) + (src.G >> 4);


Message édité par Kristoph le 22-05-2003 à 15:08:38
Reply

Marsh Posté le 22-05-2003 à 16:58:33    

Kristoph a écrit :

Et comme ca :

Code :
  1. dest.R = (src.R << 3) + (src.R >> 2);
  2. dest.G = (src.G << 2) + (src.G >> 4);




 
ouais, effectivement, ca me plait déjà un peu plus ... Je note ! :D
 
 
Edit, c'est vrai qu'utiliser les bits de poids fort pour remplir les bits de poids faible, c'est carrément cohérent quand on y réfléchit un peu .... :D


Message édité par theshockwave le 22-05-2003 à 17:02:24

---------------
last.fm
Reply

Marsh Posté le 22-05-2003 à 17:16:03    

J'ai aussi la justification du pourquoi ca marche. La voici avec le rouge :
 
On veut mapper avec une fonction lineaire l'intervale 0..31 vers 0.255
 
Il nous faut donc f(x) = x * 255 / 31
255 / 31 = 8.2258...
Moi mon calcul fait g(x) = x * 8 + x / 4 = x * (8.25)
 
Pour le cas du vert, on a : 0..63 vers 0..255 soit un coefficient de 4.047 Et j'utilise 4 + 1/16 soit 4.0675
 
CQFD :D

Reply

Marsh Posté le 22-05-2003 à 21:58:16    

Je n'étais pas ironique ... J'avais bien capté le principe ... C'est clair que j'y avais pas pensé, mais ca se tient tout à fait ... :D
 
 
Youpi :bounce: :D


Message édité par theshockwave le 22-05-2003 à 21:58:30

---------------
last.fm
Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed