todas paquetes modulos lista librerias las python image python-2.5

modulos - paquetes python



¿Cómo obtener el tamaño de imagen usando la clase estándar de Python(sin usar una biblioteca externa)? (9)

Estoy usando Python 2.5. Y usando las clases estándar de Python, quiero determinar el tamaño de la imagen de un archivo.

He escuchado PIL (Biblioteca de imágenes de Python), pero requiere que la instalación funcione.

¿Cómo puedo obtener el tamaño de una imagen sin usar ninguna biblioteca externa, solo usando los módulos de Python 2.5?

Tenga en cuenta que quiero admitir formatos de imagen comunes, particularmente JPG y PNG.


Aquí hay una manera de obtener las dimensiones de un archivo png sin necesidad de un módulo de terceros. Desde http://coreygoldberg.blogspot.com/2013/01/python-verify-png-file-and-get-image.html

import struct def get_image_info(data): if is_png(data): w, h = struct.unpack(''>LL'', data[16:24]) width = int(w) height = int(h) else: raise Exception(''not a png image'') return width, height def is_png(data): return (data[:8] == ''/211PNG/r/n/032/n''and (data[12:16] == ''IHDR'')) if __name__ == ''__main__'': with open(''foo.png'', ''rb'') as f: data = f.read() print is_png(data) print get_image_info(data)

Cuando ejecutas esto, volverá:

True (x, y)

Y otro ejemplo que incluye el manejo de archivos JPEG también: http://markasread.net/post/17551554979/get-image-size-info-using-pure-python-code


Aquí hay una secuencia de comandos de python 3 que devuelve una tupla que contiene una altura y un ancho de imagen para .png, .gif y .jpeg sin utilizar ninguna biblioteca externa (es decir, a qué se refirió Kurt McKee anteriormente). Debería ser relativamente fácil transferirlo a Python 2.

import struct import imghdr def get_image_size(fname): ''''''Determine the image type of fhandle and return its size. from draco'''''' with open(fname, ''rb'') as fhandle: head = fhandle.read(24) if len(head) != 24: return if imghdr.what(fname) == ''png'': check = struct.unpack(''>i'', head[4:8])[0] if check != 0x0d0a1a0a: return width, height = struct.unpack(''>ii'', head[16:24]) elif imghdr.what(fname) == ''gif'': width, height = struct.unpack(''<HH'', head[6:10]) elif imghdr.what(fname) == ''jpeg'': try: fhandle.seek(0) # Read 0xff next size = 2 ftype = 0 while not 0xc0 <= ftype <= 0xcf: fhandle.seek(size, 1) byte = fhandle.read(1) while ord(byte) == 0xff: byte = fhandle.read(1) ftype = ord(byte) size = struct.unpack(''>H'', fhandle.read(2))[0] - 2 # We are at a SOFn block fhandle.seek(1, 1) # Skip `precision'' byte. height, width = struct.unpack(''>HH'', fhandle.read(4)) except Exception: #IGNORE:W0703 return else: return return width, height


En cuanto a la respuesta de Fred el Fantástico :

No todos los marcadores JPEG entre C0 - CF son marcadores SOF ; Excluí DHT ( C4 ), DNL ( C8 ) y DAC ( CC ). Tenga en cuenta que no he investigado si es posible analizar los cuadros que no sean C0 y C2 de esta manera. Sin embargo, los otros parecen ser bastante raros (personalmente no he encontrado otro que C0 y C2 ).

De cualquier manera, esto resuelve el problema mencionado en los comentarios de Malandy con Bangles.jpg (DHT erróneamente analizado como SOF).

El otro problema mencionado con 1431588037-WgsI3vK.jpg se debe a que imghdr solo puede detectar los encabezados APP0 (EXIF) y APP1 (JFIF).

Esto se puede solucionar agregando una prueba más laxa a imghdr (por ejemplo, simplemente FFD8 o tal vez FFD8FF ?) O algo mucho más complejo (posiblemente incluso la validación de datos). Con un enfoque más complejo, solo he encontrado problemas con: APP14 ( FFEE ) (Adobe); el primer marcador es DQT ( FFDB ); y APP2 y problemas con ICC_PROFILE incrustados .

El código revisado a continuación, también alteró la llamada a imghdr.what() levemente:

import struct import imghdr def test_jpeg(h, f): # SOI APP2 + ICC_PROFILE if h[0:4] == ''/xff/xd8/xff/xe2'' and h[6:17] == b''ICC_PROFILE'': print "A" return ''jpeg'' # SOI APP14 + Adobe if h[0:4] == ''/xff/xd8/xff/xee'' and h[6:11] == b''Adobe'': return ''jpeg'' # SOI DQT if h[0:4] == ''/xff/xd8/xff/xdb'': return ''jpeg'' imghdr.tests.append(test_jpeg) def get_image_size(fname): ''''''Determine the image type of fhandle and return its size. from draco'''''' with open(fname, ''rb'') as fhandle: head = fhandle.read(24) if len(head) != 24: return what = imghdr.what(None, head) if what == ''png'': check = struct.unpack(''>i'', head[4:8])[0] if check != 0x0d0a1a0a: return width, height = struct.unpack(''>ii'', head[16:24]) elif what == ''gif'': width, height = struct.unpack(''<HH'', head[6:10]) elif what == ''jpeg'': try: fhandle.seek(0) # Read 0xff next size = 2 ftype = 0 while not 0xc0 <= ftype <= 0xcf or ftype in (0xc4, 0xc8, 0xcc): fhandle.seek(size, 1) byte = fhandle.read(1) while ord(byte) == 0xff: byte = fhandle.read(1) ftype = ord(byte) size = struct.unpack(''>H'', fhandle.read(2))[0] - 2 # We are at a SOFn block fhandle.seek(1, 1) # Skip `precision'' byte. height, width = struct.unpack(''>HH'', fhandle.read(4)) except Exception: #IGNORE:W0703 return else: return return width, height

Nota: Creado una respuesta completa en lugar de un comentario, ya que todavía no estoy autorizado.


Encontré una buena solución en otra publicación de (usando solo librerías estándar + que tratan con jpg también): Respuesta de JohnTESlade

Y otra solución (la forma más rápida) para aquellos que pueden permitirse ejecutar el comando '' file '' dentro de python, ejecute:

import os info = os.popen("file foo.jpg").read() print info

Salida :

foo.jpg: JPEG image data...density 28x28, segment length 16, baseline, precision 8, 352x198, frames 3

Todo lo que tienes que hacer ahora es formatear la salida para capturar las dimensiones. 352x198 en mi caso.


Ese código logra 2 cosas:

  • Obtener la dimensión de la imagen

  • Encuentra el EOF real de un archivo jpg

Bueno, cuando busqué en Google, estaba más interesado en el posterior. La tarea era cortar un archivo jpg de un flujo de datos. Dado que II no encontró ninguna forma de usar la imagen de Pythons para obtener el EOF de modo que jpg-File lo inventé.

Cosas / cambios / notas interesantes en esta muestra:

  • ampliando la clase de archivo Python normal con el método uInt16, haciendo que el código fuente sea más legible y mantenible. Jugar con struct.unpack () rápidamente hace que el código se vea feo

  • Se reemplazó la lectura de áreas / fragmentos insatisfactorios con búsqueda

  • En caso de que quiera obtener las dimensiones, puede eliminar la línea:

    hasChunk = ord(byte) not in range( 0xD0, 0xDA) + [0x00]

    -> ya que eso solo es importante cuando se lee el fragmento de datos de la imagen y se comenta

    #break

    para dejar de leer tan pronto como se encuentre la dimensión. ... pero sonría lo que estoy diciendo, usted es el codificador;)

    import struct import io,os class myFile(file): def byte( self ): return file.read( self, 1); def uInt16( self ): tmp = file.read( self, 2) return struct.unpack( ">H", tmp )[0]; jpeg = myFile(''grafx_ui.s00_//08521678_Unknown.jpg'', ''rb'') try: height = -1 width = -1 EOI = -1 type_check = jpeg.read(2) if type_check != b''/xff/xd8'': print("Not a JPG") else: byte = jpeg.byte() while byte != b"": while byte != b''/xff'': byte = jpeg.byte() while byte == b''/xff'': byte = jpeg.byte() # FF D8 SOI Start of Image # FF D0..7 RST DRI Define Restart Interval inside CompressedData # FF 00 Masked FF inside CompressedData # FF D9 EOI End of Image # http://en.wikipedia.org/wiki/JPEG#Syntax_and_structure hasChunk = ord(byte) not in range( 0xD0, 0xDA) + [0x00] if hasChunk: ChunkSize = jpeg.uInt16() - 2 ChunkOffset = jpeg.tell() Next_ChunkOffset = ChunkOffset + ChunkSize # Find bytes /xFF /xC0..C3 That marks the Start of Frame if (byte >= b''/xC0'' and byte <= b''/xC3''): # Found SOF1..3 data chunk - Read it and quit jpeg.seek(1, os.SEEK_CUR) h = jpeg.uInt16() w = jpeg.uInt16() #break elif (byte == b''/xD9''): # Found End of Image EOI = jpeg.tell() break else: # Seek to next data chunk print "Pos: %.4x %x" % (jpeg.tell(), ChunkSize) if hasChunk: jpeg.seek(Next_ChunkOffset) byte = jpeg.byte() width = int(w) height = int(h) print("Width: %s, Height: %s JpgFileDataSize: %x" % (width, height, EOI)) finally: jpeg.close()


La respuesta de Kurts necesitaba ser modificada ligeramente para que funcione para mí.

Primero, en ubuntu: sudo apt-get install python-imaging

Entonces:

from PIL import Image im=Image.open(filepath) im.size # (width,height) tuple

Consulte el handbook para obtener más información.


Si bien es posible llamar a open(filename, ''rb'') y verificar a través de los encabezados de las imágenes binarias las dimensiones, ¡parece mucho más útil instalar PIL y dedicar mucho tiempo a la creación de un excelente software nuevo! Obtiene mayor soporte de formato de archivo y la confiabilidad que proviene del uso generalizado. De la documentación de PIL , parece que el código que necesitaría para completar su tarea sería:

from PIL import Image im = Image.open(''filename.png'') print ''width: %d - height: %d'' % im.size # returns (width, height) tuple

En cuanto a escribir código usted mismo, no conozco un módulo en la biblioteca estándar de Python que haga lo que quiera. Deberá open() la imagen en modo binario y comenzar a decodificarla usted mismo. Puede leer sobre los formatos en:


Si tiene instalado ImageMagick , puede usar '' identify ''. Por ejemplo, puede llamarlo así:

path = "//folder/image.jpg" dim = subprocess.Popen(["identify","-format","/"%w,%h/"",path], stdout=subprocess.PIPE).communicate()[0] (width, height) = [ int(x) for x in re.sub(''[/t/r/n"]'', '''', dim).split('','') ]


Tropecé con este, pero puedes obtenerlo usando lo siguiente, siempre y cuando importes numpy.

import numpy as np [y, x] = np.shape(img[:,:,0])

Funciona porque ignoras todos los colores excepto uno, y luego la imagen es solo 2D, por lo que la forma te dice qué tan alta es. Todavía es un poco nuevo para Python, pero parece una forma sencilla de hacerlo.