J'ai une image brute où chaque pixel correspond à un entier non signé de 16 bits. J'essaie de lire en utilisant la fonction PIL Image.fromstring () comme dans le code suivant:
if __name__ == "__main__":
if (len(sys.argv) != 4):
print 'Error: missing input argument'
sys.exit()
file = open(sys.argv[1], 'rb')
rawData = file.read()
file.close()
imgSize = (int(sys.argv[2]), int(sys.argv[3]))
# Use the PIL raw decoder to read the data.
# - the 'F;16' informs the raw decoder that we are reading a little endian, unsigned integer 16 bit data.
img = Image.fromstring('L', imgSize, rawData, 'raw', 'F;16')
im.save('out.png')
La documentation PIL informe que le premier argument de la fonction fromstring () est 'mode'. Cependant, en regardant la documentation et la recherche sur Google, je n'ai pas pu trouver de détails sur la signification réelle de cet argument (je pense qu'il est lié à l'espace colorimétrique ou quelque chose comme ça). Quelqu'un sait-il où je peux trouver une référence plus détaillée sur la fonction fromstring () et ce que signifie l'argument mode?
La documentation spécifique se trouve sur http://effbot.org/imagingbook/concepts.htm :
Mode
Le mode d'une image définit le type et la profondeur d'un pixel dans l'image. La version actuelle prend en charge les modes standard suivants:
- 1 (1-bit pixels, black and white, stored with one pixel per byte)
- L (8-bit pixels, black and white)
- P (8-bit pixels, mapped to any other mode using a colour palette)
- RVB (pixels 3x8 bits, couleur vraie)
- RGBA (pixels 4x8 bits, vraie couleur avec masque de transparence)
- CMJN (pixels 4x8 bits, séparation des couleurs)
- YCbCr (pixels 3x8 bits, format vidéo couleur)
- I (32-bit signed integer pixels)
- F (32-bit floating point pixels)
PIL fournit également un support limité pour quelques modes spéciaux, y compris LA (L avec alpha), RGBX (vraie couleur avec remplissage) et RGBa (vraie couleur avec alpha prémultiplié).
Image.frombuffer (mode, taille, données) => image
(Nouveau dans PIL 1.1.4). Crée une mémoire d'image à partir de données de pixels dans une chaîne ou un objet tampon, en utilisant le décodeur "brut" standard. Pour certains modes, la mémoire d'image partagera la mémoire avec le tampon d'origine (cela signifie que les modifications apportées à l'objet tampon d'origine sont reflétées dans l'image). Tous les modes ne peuvent pas partager la mémoire; les modes pris en charge incluent "L", "RGBX", "RGBA" et "CMYK". Pour les autres modes, cette fonction se comporte comme un appel correspondant à la fonction fromstring.
Je ne sais pas ce que "L" signifie, mais "RGBA" signifie Rouge-Vert-Bleu-Alpha, donc je suppose que RGBX est équivalent à RGB (éditer: lors du test, ce n'est pas le cas)? CMJN est Cyan-Magenta-Yellow-Kelvin, qui est un autre type d'espace colorimétrique. Bien sûr, je suppose que si vous connaissez PIL, vous connaissez également les espaces de couleurs. Sinon, Wikipedia a un excellent article.
Quant à ce que cela signifie vraiment (si cela ne suffit pas): les valeurs des pixels seront codées différemment pour chaque espace colorimétrique. En RVB normal, vous avez 3 octets par pixel - 0-254, 0-254, 0-254. Pour Alpha, vous ajoutez un autre octet à chaque pixel. Si vous décodez une image RVB en RGBA, vous finirez par lire le pixel R à droite du premier pixel comme votre alpha, ce qui signifie que vous obtiendrez le pixel G comme valeur R. Cela sera agrandi en fonction de la taille de votre image, mais cela rendra vraiment vos couleurs changeantes. De même, essayer de lire une image encodée CMJN en RVB (ou RGBA) donnera à votre image un aspect très différent de ce qu'elle est censée faire. Par exemple, essayez ceci avec une image:
i = Image.open('image.png')
imgSize = i.size
rawData = i.tostring()
img = Image.fromstring('L', imgSize, rawData)
img.save('lmode.png')
img = Image.fromstring('RGB', imgSize, rawData)
img.save('rgbmode.png')
img = Image.fromstring('RGBX', imgSize, rawData)
img.save('rgbxmode.jfif')
img = Image.fromstring('RGBA', imgSize, rawData)
img.save('rgbamode.png')
img = Image.fromstring('CMYK', imgSize, rawData)
img.save('rgbamode.tiff')
Et vous verrez ce que font les différents modes - essayez-le avec une variété d'images d'entrée: png avec alpha, png sans alpha, bmp, gif et jpeg. C'est en fait une expérience amusante.
Si tout le reste échoue, vous pouvez toujours lire le code source. Pour PIL, les téléchargements sont ici .
Vous n'avez jamais dit exactement le format des données de pixels dans les entiers non signés 16 bits, mais je suppose que c'est quelque chose comme RRRRRGGGGGGBBBBBB, (rouge 5 bits, vert 6 bits, bleu 5 bits) ou RRRRRGGGGGBGBBBBBA (5- bits rouge, vert 5 bits, bleu 5 bits, alpha 1 bit ou transparence). Je n'ai pas vu de support pour ces formats après un coup d'œil très rapide à certaines des sources moi-même, mais je ne peux pas dire d'une manière ou d'une autre à coup sûr.
Sur la même page Web où se trouvent les téléchargements PIL, ils mentionnent que l'on peut envoyer des questions à la liste de diffusion Python Image SIG et fournir un lien pour cela. Cela pourrait être une meilleure source que de demander ici .
J'espère que cela t'aides.
C'est une vieille question, mais cela pourrait aider quelqu'un à l'avenir. L'un des problèmes avec l'extrait de code d'origine est que dans Image.fromstring('L', imgSize, rawData, 'raw', 'F;16')
, le F;16
une partie fonctionne pour 'F'
mode.
Cela fonctionne pour moi:
image = Image.fromstring('F', imgSize, rawData, 'raw', 'F;16')
image.convert('L').save('out.png')