11
votes

Convertir de la couleur hexagonale en structure RVB en C

Comment convertissez-vous du code hexagonal de couleur en RVB dans Pure C à l'aide de la bibliothèque C uniquement (sans C ++ ou modèles)? La struct RGB peut être comme ceci: xxx

La fonction que je cherche devrait renvoyer RGB1.


1 commentaires

Je ne suis pas sûr de comprendre la question. Je crois que les choses qui signalent que le code et / ou l'insertion de nouvelles lignes dans la question dans les lieux stratégiques peuvent être utiles pour rendre la question plus facile à lire (et donc à répondre).


5 Réponses :


13
votes

Une valeur RVB peut être stockée comme entier via 0xRRGGBBB. Exemples:

  • Rouge: 0xFF0000
  • Vert: 0x00FF00
  • Bleu: 0x0000FF

    00 est hexagone pour une décimale 0, tandis que FF est 255. 0 correspond à 0,0 et 255 à 1,0. (En fait, vous n'avez pas précisé quelle est la gamme. Je suppose 0,0 à 1.0.)

    Ainsi, avec les hypothèses ci-dessus, vous devez extraire chaque composant et diviser par 255. Comme cela semble beaucoup Comme une question de devoirs, je vais simplement vous montrer comment vous pouvez faire le composant rouge. xxx

    Chaque chiffre hexagonal prend 4 bits. Alors, passez à droite par 16 bits (pour déplacer tout 4 chiffres à droite) pour faire 0xrgrgbb devenir 0xrr . Maintenant, vous avez le composant rouge. (Juste au cas où il y a des données plus haut dans l'entier, vous pouvez vous en débarrasser en masquant les données via & 0xFF .)

    Si vous avez affaire à une chaîne "# ffffff" , alors vous devez d'abord la convertir en un entier pour le travail ci-dessus.


0 commentaires

25
votes

En supposant que votre valeur hexagonale est un type "INT '32 bits" et que nous utilisons la structure RVB décrite ci-dessus, peut-être faire quelque chose comme: xxx


4 commentaires

Type d'arrière de la réponse @konforce a donné n'est-ce pas?


Nah. Il y avait aussi du code pour le traitement des cordes, mais le point Konforce a fait à propos de cela probablement une question de devoirs était une bonne chose. Ainsi, j'ai édité cette réponse pour être plus comme celui de Kon posté ci-dessus.


L'hexvalue devrait-il être de type non signé INT? Je pense que le & 0xFF annule le décalage arithmétique, mais une valeur comme 0xFFFFFF provoque un débordement lorsqu'il est passé?


'Unsigné Int' serait probablement un peu plus gentil. Cela dit, dans ce cas, cela ne comporterait pas vraiment car RRGGBB s'adapte à 24 bits, et un type «INT» est (assez universellement) 32 bits de longueur. Cette réponse suppose que les bits RRGGBB sont rangés d'une certaine manière dans l'INT, bien que ... si caverné.



1
votes

Je suppose que RGB pourrait être stocké comme 0xrggBBB sur certains systèmes, mais sous Windows, il est réellement stocké comme 0xbbggrr (voir http://msdn.microsoft.com/en-us/library/windows/desktop/dd183449 ). Comme le mentionne l'article, il existe des macros getrvalue, Getgvalue et GetBvalue déjà disponibles.


0 commentaires

17
votes

Si le code hexadécimal est une chaîne, vous pouvez l'analyser comme celui-ci

char *str = "0000FF";
int r, g, b;
sscanf(str, "%02x%02x%02x", &r, &g, &b);


3 commentaires

Utilisez la chaîne de format "% 2HX% 2HX% 2HX" Si vous souhaitez l'analyser dans non signé courte valeurs


J'ai utilisé sscanf (str.c_str (), "% 02hhx% 02hhx% 02hx", & r, & g, & b); avec un std :: string pour l'analyser dans non signé Char valeurs,


Je ne peux pas uplifier assez la réponse de Tor! Solution élégante.



4
votes

Je sais que c'est assez vieux, mais je voulais aussi donner une solution avec les syndicats et sans aucune opération de manipulation de bits.

union Color
{
    unsigned int hex;

#if IS_BIG_ENDIAN
    struct { unsigned char a, r, g, b; };
#else
    struct { unsigned char b, g, r, a; };
#endif
};


13 commentaires

Bonne réponse, mais vous devriez vérifier l'endansion pour que la réponse soit complète. Voir Stackoverflow.com/q/18863913/8339821 pour une référence.


Bon point, je ferai des tests et mettra à jour la réponse.


Génial, veuillez commenter quand vous faites une mise à jour. MB vous obtiendrez un uppote;)


@YVW J'ai mis à jour la réponse qui prend en charge les deux endansnités, j'étais très incertaine si les systèmes Windows ne sont que peu-Endian, ont fini par utiliser une macro de contrôle de la CPU.


Le BSD semble avoir comme . D'autres systèmes peuvent ne pas avoir l'en-tête.


@YVW J'ai ajouté BSD et Mac OS.


D'où vient tous ceux qui définissent? Par exemple, FreeBSD Manuel nous dit que __ FreeBSD __ est défini dans toutes les versions de FreeBSD . Je ne vois pas os_freebsd défini sur ma machine FreeBSD. Peut-être devriez-vous quitter la question du système d'exploitation? Vous pouvez faire une remarque sur votre réponse que vous avez deux extraits de code. Un pour le petit Endian et un pour d'autres.


@YVW HMM ... J'ai vu une liste de macros de préprocesseur de certains systèmes sur un gist GitHub. Je viens de faire un revérificateur de cela, et je l'ai résolu. J'ai trouvé que __ big_endian __ est défini par clang et gcc sans , peut-être que je devrais mettre à jour le code pour l'utiliser à la place? Et j'ai également précisé qu'une bibliothèque multiplate-forme ferait mieux pour cela, peut-être quelque chose comme Boost Endian, mais je suis sûr que ce n'est que pour C ++.


Je regarde FreeBSD blob et ne vois aucun _big_endian définir là-bas. Il n'y a que _little_endian . Je pense que vous devriez arrêter de copier / coller du git aléatoire.


Je l'ai vu sur github.com/openbsd/src/blob/ MASTER / SYS / SYS / ENDIAN.H Je pense que je vais simplement rediriger vers une autre question sur scaleverflow lorsqu'il s'agit de l'endansion. Et juste montrer les deux exemples pour les petits et grands Endian.


Ce sera un bon appel. Vérifiez les autres réponses tho. Ils n'ont pas à deviner l'endianesse, ils travaillent toujours. Soyez juste prudent avec Union S dans C .


Personnellement, j'utilise à peine des syndicats, je voulais juste montrer une façon différente de faire la même chose. :) Je n'utiliserais probablement jamais quelque chose comme celui-ci, en raison de la diminution de la performance (14 fois plus lente que le bit dans le sens) et en raison de limitations compilateurs / endians. Mais je pense que c'est bien de connaître plusieurs façons de faire les mêmes choses, même s'ils ne sont pas les meilleurs. Une autre façon de le faire serait en utilisant non signé Char RGBA [4] et utilisez des getters / Setters qui vérifient l'endansion du système pour se comporter en conséquence. Peut-être que je devrais ajouter ça aussi?


Il suffit de quitter le problème de l'endansion. Ceux qui pourraient utiliser votre code doivent s'en occuper. En dehors de cela, si votre code ajoute quelque chose de nouveau aux réponses, n'hésitez pas à commettre.