Je comprends que vous pouvez obtenir la taille de l'image à l'aide de PIL de la manière suivante
from PIL import Image
im = Image.open(image_filename)
width, height = im.size
Cependant, je voudrais obtenir la largeur et la hauteur de l'image sans avoir à charger l'image en mémoire. Est-ce possible? Je ne fais que des statistiques sur les tailles d'image et ne me soucie pas du contenu de l'image. Je veux juste accélérer mon traitement.
python
image
image-processing
Sami A. Haija
la source
la source
.open()
lit le fichier entier en mémoire ... (c'est ce que.load()
) fait - donc pour autant que je sache - c'est aussi bon que possiblePIL
pmap
pour surveiller la mémoire utilisée par un processus me montre qu'en effetPIL
ne charge pas toute l'image en mémoire.Réponses:
Comme l'indiquent les commentaires, PIL ne charge pas l'image en mémoire lors de l'appel
.open
. En regardant la documentation dePIL 1.1.7
, la docstring for.open
dit:Il y a quelques opérations sur les fichiers dans la source comme:
mais ceux-ci ne constituent guère la lecture de l'ensemble du dossier. En fait,
.open
renvoie simplement un objet fichier et le nom du fichier en cas de succès. De plus, les documents disent:En creusant plus profondément, nous voyons que les
.open
appels_open
sont une surcharge spécifique au format d'image. Chacune des implémentations à_open
peut être trouvée dans un nouveau fichier, par exemple. Les fichiers .jpeg sont au formatJpegImagePlugin.py
. Examinons celui-ci en profondeur.Ici, les choses semblent devenir un peu délicates, il y a une boucle infinie qui se rompt lorsque le marqueur jpeg est trouvé:
Ce qui semble pouvoir lire tout le fichier s'il était mal formé. S'il lit le marqueur d'information OK, cependant, il devrait sortir tôt. La fonction
handler
définit finalementself.size
quelles sont les dimensions de l'image.la source
open
obtient-il la taille de l'image ou est-ce aussi une opération paresseuse? Et s'il est paresseux, lit-il les données d'image en même temps?Docs/PIL.Image.html
..jpeg
format semble correct tant que l'en-tête est trouvé.Si vous ne vous souciez pas du contenu de l'image, PIL est probablement exagéré.
Je suggère d'analyser la sortie du module magique python:
Il s'agit d'un wrapper autour de libmagic qui lit le moins d'octets possible afin d'identifier une signature de type de fichier.
Version pertinente du script:
https://raw.githubusercontent.com/scardine/image_size/master/get_image_size.py
[mettre à jour]
On dirait que les jpegs sont résistants à la magie. :-)
Je peux comprendre pourquoi: pour obtenir les dimensions de l'image pour les fichiers JPEG, vous devrez peut-être lire plus d'octets que libmagic aime lire.
J'ai retroussé mes manches et je suis venu avec cet extrait de code non testé (obtenez-le sur GitHub) qui ne nécessite aucun module tiers.
[mise à jour 2019]
Découvrez une implémentation de Rust: https://github.com/scardine/imsz
la source
UnicodeDecodeError: 'utf-8' codec can't decode byte 0x89 in position 0: invalid start byte
sur MacOS, python3 surdata = input.read(25)
,file
sur l'image donnePNG image data, 720 x 857, 8-bit/color RGB, non-interlaced
Il existe un package sur pypi appelé
imagesize
qui fonctionne actuellement pour moi, bien qu'il ne semble pas être très actif.Installer:
Usage:
Page d'accueil: https://github.com/shibukawa/imagesize_py
PyPi: https://pypi.org/project/imagesize/
la source
Je récupère souvent des tailles d'image sur Internet. Bien sûr, vous ne pouvez pas télécharger l'image, puis la charger pour analyser les informations. Cela prend trop de temps. Ma méthode consiste à alimenter en morceaux un conteneur d'image et à tester s'il peut analyser l'image à chaque fois. Arrêtez la boucle lorsque j'obtiens les informations que je veux.
J'ai extrait le noyau de mon code et l'ai modifié pour analyser les fichiers locaux.
Production:
La taille réelle du fichier est de 1 543 580 octets et vous ne lisez que 38 912 octets pour obtenir la taille de l'image. J'espère que cela aidera.
la source
Une autre façon rapide de le faire sur les systèmes Unix. Cela dépend de la sortie
file
dont je ne suis pas sûr qu'elle soit normalisée sur tous les systèmes. Cela ne devrait probablement pas être utilisé dans le code de production. De plus, la plupart des JPEG ne signalent pas la taille de l'image.la source
IndexError: list index out of range
Cette réponse a une autre bonne résolution, mais il manque le format pgm . Cette réponse a résolu le pgm . Et j'ajoute le bmp .
Les codes sont ci-dessous
la source
imghdr
cependant gère assez mal certains jpeg.