Lectura de archivos bmp en Python
Frecuentes
Visto 51,604 veces
18
¿Hay alguna forma de leer un archivo bmp en Python que no implique el uso de PIL? PIL no funciona con la versión 3, que es la que tengo. Traté de usar el objeto Imagen de graphics.py, Imagen (punto de anclaje, nombre de archivo), pero parece que solo funciona con archivos gif.
8 Respuestas
15
En Python, simplemente se puede leer como:
import os
from scipy import misc
path = 'your_file_path'
image= misc.imread(os.path.join(path,'image.bmp'), flatten= 0)
## flatten=0 if image is required as it is
## flatten=1 to flatten the color layers into a single gray-scale layer
Respondido 01 Abr '14, 20:04
Nota, en SciPy 1.0 imread (etc.) se deprecia y se eliminará en 1.2; SciPy 1.2 utilizará imageio.imread
- UH oh
7
Me doy cuenta de que esta es una vieja pregunta, pero la encontré al resolver este problema yo mismo y pensé que esto podría ayudar a alguien más en el futuro.
En realidad, es bastante fácil leer un archivo BMP como datos binarios. Dependiendo de qué tan amplio sea el soporte y cuántos casos de esquina necesites soportar, por supuesto.
A continuación se muestra un analizador simple que SÓLO funciona para BMP de 1920 bits de 1080x24 (como los guardados de MS Paint). Sin embargo, debería ser fácil de extender. Escupe los valores de píxeles como una lista de python como (255, 0, 0, 255, 0, 0, ...)
para una imagen roja como ejemplo.
Si necesita un soporte más sólido, hay información sobre cómo leer correctamente el encabezado en las respuestas a esta pregunta: ¿Cómo leer el encabezado del archivo bmp en python?. Usando esa información, debería poder ampliar el analizador simple a continuación con las características que necesita.
También hay más información sobre el formato de archivo BMP en wikipedia https://en.wikipedia.org/wiki/BMP_file_format si lo necesitas.
def read_rows(path):
image_file = open(path, "rb")
# Blindly skip the BMP header.
image_file.seek(54)
# We need to read pixels in as rows to later swap the order
# since BMP stores pixels starting at the bottom left.
rows = []
row = []
pixel_index = 0
while True:
if pixel_index == 1920:
pixel_index = 0
rows.insert(0, row)
if len(row) != 1920 * 3:
raise Exception("Row length is not 1920*3 but " + str(len(row)) + " / 3.0 = " + str(len(row) / 3.0))
row = []
pixel_index += 1
r_string = image_file.read(1)
g_string = image_file.read(1)
b_string = image_file.read(1)
if len(r_string) == 0:
# This is expected to happen when we've read everything.
if len(rows) != 1080:
print "Warning!!! Read to the end of the file at the correct sub-pixel (red) but we've not read 1080 rows!"
break
if len(g_string) == 0:
print "Warning!!! Got 0 length string for green. Breaking."
break
if len(b_string) == 0:
print "Warning!!! Got 0 length string for blue. Breaking."
break
r = ord(r_string)
g = ord(g_string)
b = ord(b_string)
row.append(b)
row.append(g)
row.append(r)
image_file.close()
return rows
def repack_sub_pixels(rows):
print "Repacking pixels..."
sub_pixels = []
for row in rows:
for sub_pixel in row:
sub_pixels.append(sub_pixel)
diff = len(sub_pixels) - 1920 * 1080 * 3
print "Packed", len(sub_pixels), "sub-pixels."
if diff != 0:
print "Error! Number of sub-pixels packed does not match 1920*1080: (" + str(len(sub_pixels)) + " - 1920 * 1080 * 3 = " + str(diff) +")."
return sub_pixels
rows = read_rows("my image.bmp")
# This list is raw sub-pixel values. A red image is for example (255, 0, 0, 255, 0, 0, ...).
sub_pixels = repack_sub_pixels(rows)
respondido 20 nov., 17:12
2
Tuve que trabajar en un proyecto en el que necesitaba leer un archivo BMP usando python, fue bastante interesante, en realidad la mejor manera es tener una revisión del formato de archivo BMP (https://en.wikipedia.org/wiki/BMP_file_format) y luego leerlo como un archivo binario, para extraer los datos.
Deberá usar la biblioteca struct python para realizar la extracción
Puedes usar este tutorial para ver cómo procede. https://youtu.be/0Kwqdkhgbfw
contestado el 27 de mayo de 20 a las 05:05
1
Depende de lo que esté tratando de lograr y en qué plataforma.
De todos modos, usar una biblioteca C para cargar BMP puede funcionar, por ejemplo http://code.google.com/p/libbmp/ or http://freeimage.sourceforge.net/, y las bibliotecas C se pueden llamar fácilmente desde python, por ejemplo, usando ctypes o envolviéndolo como un módulo de python.
o puede compilar esta versión de PIL https://github.com/sloonz/pil-py3k
contestado el 03 de mayo de 12 a las 22:05
Ctypes es viable, y lo he usado y me he quedado con él, pero tiende a producir soluciones relativamente frágiles, más que C en sí mismo. Eso es porque la verificación de tipos podría ser mejor con ctypes. Para una API muy estable, los ctypes pueden ser bastante buenos (especialmente si desea apuntar no solo a cpython sino también a pypy), pero cython podría ser mejor para muchas cosas si está dispuesto a seguir con cpython. - user1277476
1
Si está haciendo esto en Windows, este sitio debería permitirle obtener PIL (y muchos otros paquetes populares) en funcionamiento con la mayoría de las versiones de Python: Binarios de Windows no oficiales para paquetes de extensión de Python
contestado el 03 de mayo de 12 a las 22:05
1
El puerto común de PIL a Python 3.x se llama "Pillow". También sugeriría la biblioteca pygame para tareas simples. Es una biblioteca, llena de funciones para crear juegos, y la lectura de algunos formatos de imagen comunes se encuentra entre ellas. También funciona con Python 3.x.
Respondido 04 ago 13, 23:08
1
Usa una almohada para esto. Después de instalarlo, simplemente impórtelo
from PIL import Image
Entonces puedes cargar el archivo BMP
img = Image.open('path_to_file\file.bmp')
Si necesita que la imagen sea una matriz numpy, use np.array
img = np.array(Image.open('path_to_file\file.bmp'))
La matriz numpy solo será 1D. Usar reshape()
para darle la forma correcta en caso de que su imagen sea RGB. Por ejemplo:
np.array(Image.open('path_to_file\file.bmp')).reshape(512,512,3)
Respondido el 21 de diciembre de 20 a las 17:12
0
Use la excelente biblioteca matplotlib
import matplotlib.pyplot as plt
im = plt.imread('image.bmp')
contestado el 20 de mayo de 21 a las 13:05
No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas python python-3.x or haz tu propia pregunta.
En esta página afirma tener versiones de PIL compatibles con Python 3. - Thomas K