Python: abre el archivo en zip sin extraerlo temporalmente


82

¿Cómo puedo abrir archivos en un archivo zip sin extraerlos primero?

Estoy usando pygame. Para ahorrar espacio en disco, tengo todas las imágenes comprimidas. ¿Es posible cargar una imagen determinada directamente desde el archivo zip? Por ejemplo: pygame.image.load('zipFile/img_01')


2
¿Qué tipo de archivos de imagen? GIF, JPEG y PNG ya están comprimidos.
hughdbrown

Respuestas:


109

La respuesta de Vincent Povirk no funcionará por completo;

import zipfile
archive = zipfile.ZipFile('images.zip', 'r')
imgfile = archive.open('img_01.png')
...

Tienes que cambiarlo en:

import zipfile
archive = zipfile.ZipFile('images.zip', 'r')
imgdata = archive.read('img_01.png')
...

Para obtener más información, lea los ZipFiledocumentos aquí .


image = pygame.image.load (imgfile, 'img_01.png') TypeError: debe ser una cadena sin bytes nulos, no str
user2880847

Explique su cambio. read devuelve una cadena con el contenido del archivo; open devuelve un objeto similar a un archivo. La documentación de pygame dice que image.load quiere un nombre de archivo o un objeto similar a un archivo.
Esme Povirk

@Vincent Povirk: Gracias por comentar. El problema sigue siendo que image.load acepta un objeto similar a un archivo, pero no acepta el objeto zip-file. Tienes que adaptarte a eso de alguna manera. Tampoco estoy convencido de mi respuesta, aún no es elegante ...
Jellema

21
import io, pygame, zipfile
archive = zipfile.ZipFile('images.zip', 'r')

# read bytes from archive
img_data = archive.read('img_01.png')

# create a pygame-compatible file-like object from the bytes
bytes_io = io.BytesIO(img_data)

img = pygame.image.load(bytes_io)

Estaba tratando de resolver esto por mí mismo hace un momento y pensé que esto podría ser útil para cualquiera que se encuentre con esta pregunta en el futuro.


8

En teoría, sí, es solo una cuestión de conectar cosas. Zipfile puede darle un objeto similar a un archivo para un archivo en un archivo zip, e image.load aceptará un objeto similar a un archivo. Entonces, algo como esto debería funcionar:

import zipfile
archive = zipfile.ZipFile('images.zip', 'r')
imgfile = archive.open('img_01.png')
try:
    image = pygame.image.load(imgfile, 'img_01.png')
finally:
    imgfile.close()
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.