Lectura de archivos bmp en Python

¿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.

preguntado el 03 de mayo de 12 a las 21:05

En esta página afirma tener versiones de PIL compatibles con Python 3. -

8 Respuestas

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

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

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

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

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

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

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

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 or haz tu propia pregunta.