Comment convertir 16 bits RGB565 à 24 bits RGB888?
J'ai eu mes mains sur 16 bits rgb565 image (plus précisément, un Android framebuffer dump), et je voudrais le convertir en 24 bits rgb888 pour l'affichage sur un moniteur normal.
La question est, comment convertir 5 ou 6 bits de canal à 8 bits? La réponse est évidente pour le déplacer. J'ai commencé par écrit ceci:
puts("P6 320 480 255");
uint16_t buf;
while (read(0, &buf, sizeof buf)) {
unsigned char red = (buf & 0xf800) >> 11;
unsigned char green = (buf & 0x07e0) >> 5;
unsigned char blue = buf & 0x001f;
putchar(red << 3);
putchar(green << 2);
putchar(blue << 3);
}
Cependant, ce n'est pas une propriété que je voudrais, ce qui est pour 0xffff
à la carte de 0xffffff
, au lieu de 0xf8fcf8
. J'ai besoin d'accroître la valeur d'une certaine façon, mais je ne suis pas sûr de savoir comment cela devrait fonctionner.
Le SDK Android est livré avec un outil appelé ddms (Dalvik Debug Monitor) qui prend des captures d'écran. Aussi loin que je peux dire de la lecture du code, il met en œuvre la même logique; mais sa captures d'écran viennent de sortir différents, et le blanc est la cartographie de blanc.
Voici la raw framebuffer, le conversion intelligente par ddms, et la la conversion idiote par l'algorithme ci-dessus. A noter que ce dernier est légèrement plus foncée et plus écologique.
(En passant, cette conversion est mis en œuvre dans ffmpeg, mais il est juste d'effectuer la conversion idiote énumérés ci-dessus, laissant le Lsb à tous les zéro.)
Je suppose que j'ai deux questions:
- Ce qui est la façon la plus sensée pour convertir rgb565 à rgb888?
- Comment est DDMS à la conversion de ses captures d'écran?
Vous devez vous connecter pour publier un commentaire.
Vous pouvez changer et puis ou avec les bits les plus significatifs; c'est à dire
Ce qui a la propriété que vous recherchez, mais c'est pas le plus linéaire de la cartographie des valeurs d'un espace à l'autre. C'est rapide, cependant. 🙂
Cletus réponse est plus complète et probablement mieux. 🙂
Vous souhaitez mapper chacune de ces à partir d'un 5/6 peu d'espace pour une 8 bits de l'espace.
Le code que vous utilisez est en prenant l'approche naïve que x5 * 256/32 = x8 où 256/32 = 8 et en multipliant par 8 est de décalage vers la gauche 3 mais, comme vous le dites, ce n'est pas nécessairement remplir le nouveau numéro de l'espace "correctement". 5 à 8 pour une valeur maximum de 31 à 255 et c'est là que réside votre indice de la solution.
où
x5
,x6
etx8
sont 5, 6 et 8 bits respectivement les valeurs.Maintenant, il ya une question à propos de la meilleure façon de le mettre en œuvre. Il n'impliquent de la division et division entière, vous perdrez tout reste conséquent (arrondi à l'inférieur essentiellement) donc, la meilleure solution est probablement de le faire arithmétique à virgule flottante et ensuite le tour de la moitié jusqu'à revenir à un nombre entier.
Ce peut être accéléré considérablement simplement à l'aide de cette formule pour générer une table de recherche pour chacun des 5 et 6 bits de conversions.
Mes quelques cents:
Si vous vous souciez de la cartographie précise, mais un algorithme rapide, vous pouvez considérer ceci:
Il utilise seulement: MUL, d'AJOUTER et de SHR -> donc c'est assez rapide!
De l'autre côté, il est compatible à 100% à virgule flottante de cartographie avec une bonne arrondissement:
Supplémentaire cents:
Si vous êtes intéressé à 888 565 conversion, cela fonctionne très bien aussi:
Constantes ont été trouvés en utilisant la force brute de recherche avec somę début des rejets à la vitesse de chose un peu.
iOS vImage de Conversion
La iOS Accélérer le Cadre documents de l'algorithme suivant pour la
vImageConvert_RGB565toARGB8888
fonction:De conversion ce sera assez rapide, mais si vous voulez traiter de nombreux cadres vous voulez utiliser quelque chose comme l'iOS vImage de conversion ou de mettre en œuvre vous-même à l'aide de NEON intrinsèques.
De Bras De La Communauté Du Forum Tutoriel
Pour Android exemple précis, j'ai trouvé un YUV-à-conversion RGB écrit dans intrinsèques.
Essayez ceci:
Ce sera une carte de tous les zéros dans tous les zéros, tous les 1 dans tous les 1, et tout ce qui entre dans tout entre les deux. Vous pouvez la rendre plus efficace en déplaçant les bits en place en une seule étape:
Faire de même pour le vert et le bleu (pour 6 bits, maj gauche 2 et 4 respectivement dans le haut de la méthode).
La solution générale est de traiter les nombres en binaire fractions - ainsi, le 6 nombre de bits 63/63 est le même que les 8 bits du nombre 255/255. Vous pouvez la calculer à l'aide de calcul en virgule flottante initialement, puis de calculer une table de choix, comme d'autres affiches suggèrent. Cela a aussi l'avantage d'être plus intuitive que peu de dénigrement systématique de solutions. 🙂
Il y a une erreur jleedev !!!
le bon code
Cheers,
Andy
J'ai utilisé la commande suivante et obtenu de bons résultats. S'est avéré que mon Logitek cam était 16bit RGB555 et à l'aide de la suite à se convertir à 24bit RGB888 m'a permis d'enregistrer au format jpeg à l'aide de petits animaux ijg: Merci pour l'astuce trouvée ici sur stackoverflow.