Czy istnieje sposób na odczyt w pliku bmp w Pythonie, który nie wymaga użycia PIL? PIL nie działa z wersją 3, którą mam. Próbowałem użyć obiektu Image z graphics.py, Image (anchorPoint, filename), ale to zdaje się działać tylko z plikami GIF.Czytanie plików bmp w Pythonie
Odpowiedz
Zależy od tego, co próbujesz osiągnąć i na jakiej platformie?
W każdym razie użycie biblioteki C do załadowania BMP może działać np. http://code.google.com/p/libbmp/ lub http://freeimage.sourceforge.net/, a biblioteki C można łatwo wywołać z Pythona np. przy użyciu ctypes lub owijając go jako moduł python.
czy można skompilować tę wersję PIL https://github.com/sloonz/pil-py3k
Ctypes jest wykonalny, a ja go użyłem i utknąłem z nim, ale generuje on raczej kruche rozwiązania - bardziej niż samo C. To dlatego, że sprawdzanie typów może być lepsze dzięki ctypes. Dla bardzo stabilnego API, ctypes może być całkiem niezły (szczególnie, jeśli chcesz celować nie tylko w cpython, ale także w pypy), ale cyton może być lepszy dla wielu rzeczy, jeśli chcesz trzymać się cpythona. – user1277476
Jeśli robisz to w Windows, ta strona powinna pozwalają uzyskać PIL (i wiele innych popularnych pakietów) i działa z większością wersji Pythona : Unofficial Windows Binaries for Python Extension Packages
Wspólny port PIL do Python 3.x jest nazywany "Pillow". Proponuję także bibliotekę pygame dla prostych zadań. Jest to biblioteka, pełna funkcji do tworzenia gier - i wśród nich jest czytanie z popularnych formatów graficznych. Działa również z Pythonem 3.x.
W Pythonie można go po prostu odczytać jako:
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
Uwaga, w SciPy 1.0 [imread (etc.) jest amortyzowany i zostanie usunięty w wersji 1.2] (https://docs.scipy.org/doc/scipy/reference/generated/scipy.misc.imsave.html#scipy. misc.imread); SciPy 1.2 użyje 'imageio.imread' – uhoh
Zdaję sobie sprawę, że jest to stara sprawa, ale znalazłem go podczas rozwiązywania tego problemu się i pomyślałem, że to może pomóc komuś w przyszłości .
Dosyć łatwo jest odczytać plik BMP jako dane binarne. W zależności od tego, jak szerokie wsparcie i jak wiele przypadków narożnych trzeba wspierać oczywiście.
Poniżej znajduje się prosty analizator składniowy, który działa TYLKO dla 24-bitowych BMP 1920x1080 (jak te zapisane z MS Paint). Powinno być jednak łatwe do rozszerzenia. Pluje wartości piksela jako listę pytonów, taką jak (255, 0, 0, 255, 0, 0, ...)
, dla przykładu z czerwonym obrazem.
Jeśli potrzebujesz bardziej niezawodnego wsparcia, w odpowiedzi na to pytanie znajdziesz informacje, jak prawidłowo odczytać nagłówek: How to read bmp file header in python?. Korzystając z tych informacji, powinieneś być w stanie rozszerzyć prosty parser poniżej o dowolne potrzebne funkcje.
Istnieje również więcej informacji na temat formatu pliku BMP na stronie wikipedia https://en.wikipedia.org/wiki/BMP_file_format, jeśli jest to potrzebne.
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)
[Ta strona] (http://www.lfd.uci.edu/~gohlke/pythonlibs/#pil) twierdzi, że ma wersje PIL zgodne z Python 3. –