GetDIBits et boucle sur les pixels à l'aide de X, Y
Je passe une partie de l'écran et la numérisation à travers les pixels pour une certaine gamme de couleurs.
J'ai regardé MSDN est la Capture d'une Image exemple et de savoir comment utiliser les fonctions.
Je peux obtenir les bits dans un tableau, mais je ne suis pas sûr de savoir comment le faire de telle manière que je peux faire une boucle par elle que je voudrais une image. Un pseudo-exemple (dont je suis sûr, c'est loin):
for ( x = 1; x <= Image.Width; x += 3 )
{
for ( y = 1; y <= Image.Height; y += 3 )
{
red = lpPixels[x];
green = lpPixels[x + 1];
blue = lpPixels[x + 2];
}
}
C'est en gros ce que je veux faire, donc si le rouge, le bleu et le vert est une couleur, je vais savoir ce que coordonnées, c'est à (x, y) dans l'image.
Je ne sais pas comment GetDIBits de telle manière, et comment configurer le tableau de manière appropriée pour être en mesure d'accomplir cette tâche.
OriginalL'auteur guitar- | 2010-09-10
Vous devez vous connecter pour publier un commentaire.
Outre les bonnes réponses déjà données, voici un exemple de comment pour obtenir une simple structure de tableau pour la marche. (Vous pouvez utiliser, par exemple, Goz' code pour l'itération.)
GetDIBits de référence @ MSDN
Vous devez sélectionner
DIB_RGB_COLORS
comme drapeau pouruUsage
et configurer leBITMAPINFO
de la structure et laBITMAPINFOHEADER
de la structure qu'il contient. Lorsque vous définissezbiClrUsed
etbiClrImportant
à zéro, il n'y a "pas" de la table des couleurs, ainsi vous pouvez lire les pixels de l'image bitmap que vous obtenez à partirGetDIBits
comme une séquence de valeurs RVB. À l'aide de32
comme le nombre de bits (biBitCount
) définit la structure de données selon la MSDN:Depuis un MS
LONG
est exactement 32 bits de long (de la taille d'unDWORD
), vous n'avez pas à payer l'attention sur le rembourrage (comme décrit dans la Section remarques).Code:
Vous avez raison, merci pour repérer l'erreur. Je pense que c'est corrigé maintenant, j'ai déménagé l'initialisation avant le premier appel à
GetDIBits
; autant que je sache, il n'est pas nécessaire de re-initialiser après le premier appel.Hmmm. Je ne suis pas sûr à ce sujet. J'ai essayé ceci dans mon code et si je fais le deuxième appel à GetDIBits j'obtiens une erreur que la structure locale obtient un Dépassement de tampon sur la pile... enfin, je suis retourné à une solution j'initialise la structure de la main. Dans certains cas, vous ne voulez pas avoir une compression. Resuing la informatiuon de réutilisation de la compression... je ne suis pas si sûr que ce soit vrai. Mais je n'ai pas eu le temps de vérifier.
Réponse très, très utile. Mais j'ai du retirer la demande pour les 32 bits, sinon, la 2e GetDIBits échec de l'appel. Aucune idée de pourquoi 🙂
J'ai eu le même problème. Après le 1er appel biCompression est fixé à 3, de sorte que la valeur 0 est essentielle afin d'éviter extra 3 DWORDs être écrite à la fin de la structure.
OriginalL'auteur
GetDIBits
retourne un tableau à une dimension de valeurs. Pour un bitmap de M pixels de large par N pixels de haut et utilise la couleur 24 bits, la première (M*3) octets sera la première ligne de pixels. Qui peut être suivie par des octets de remplissage. Il dépend de la BITMAPINFOHEADER. Il est généralement de rembourrage pour faire de la largeur d'un multiple de 4 octets. Donc, si votre image est de 33 pixels de large, il sera effectivement (36*3) octets par ligne.Cette "pixels plus rembourrage" est appelé le "stride". Pour le RVB images bitmap, vous pouvez calculer la foulée avec:
stride = (biWidth * (biBitCount /8) + 3) & ~3
, oùbiWidth
etbiBitCount
sont prises à partir de la BITMAPINFOHEADER.Je ne suis pas sûr de savoir comment vous voulez parcourir le tableau. Si vous voulez aller de pixel-par-pixel en haut à gauche à en bas à droite (en supposant que c'est un top-down bitmap):
enfin un exemple qui prend la foulée en considération...au lieu d'exiger une conversion de 32 bits en premier 🙂
OriginalL'auteur Jim Mischel
Il n'est pas si facile. Votre algorithme dépendra de la profondeur de couleur de l'image. Si c'est de 256 ou moins, vous n'aurez pas de pixel de couleurs, mais des indices dans une palette de couleurs. Pixels 16 bits pourrait être RGB555 ou RGB565, les images 24 bits sera RGB888, et les images 32 bits sera RGBA ou ARGB. Vous aurez besoin de la BITMAPINFOHEADER pour le savoir.
Une fois que vous découvrez, les données de pixel sera juste un tableau de taille largeur * hauteur * (BitsPerPixel /8)
Je pense que l'OP sélectionne l'image bitmap dans le DeviceContext, donc, a le plein contrôle sur l'image bitmap. À l'aide de 24 bits et pas de compression permettent de lire RGB888 facilement.
OriginalL'auteur James
Dans le lien que vous postez vous créer un bitmap 32 bits donc je vais supposer que vous lisez à partir d'un bitmap 32 bits (Cette hypothèse est peut-être incorrect).
Donc de changer votre boucle à la suivante devrait fonctionner:
Choses à garder à l'esprit:
1.Les tableaux sont de 0 basée en C/C++
2. Vous étiez étape 3 pixels horizontalement et verticalement à chaque fois. Ce qui veut dire que vous n'êtes pas à visiter chaque pixel.
3. Une image bitmap est généralement organisée de manière telle qu'il y a la "hauteur" s'étend de la "largeur" de pixels. Par conséquent, vous devriez étape à travers chaque pixel d'une plage, puis passer à la prochaine portée.
4. Comme l'a déjà souligné, assurez-vous de l'aar lecture de pixels correctement. en mode 16 bits de ses plus complexe
OriginalL'auteur Goz
Une certaine surprise de MSDN:
donc, les couleurs sont dans BGR ordre dans la mémoire après GetDIBits()
OriginalL'auteur Крутой Инфо