2012-05-03 29 views
8

Có cách nào để đọc trong tệp bmp bằng Python không liên quan đến việc sử dụng PIL không? PIL không hoạt động với phiên bản 3, là phiên bản tôi có. Tôi đã cố gắng sử dụng đối tượng Image từ graphics.py, Image (anchorPoint, filename), nhưng điều đó dường như chỉ hoạt động với các tệp gif.Đọc các tệp bmp bằng Python

+0

[Trang này] (http://www.lfd.uci.edu/~gohlke/pythonlibs/#pil) tuyên bố có Python 3 phiên bản tương thích của PIL. –

Trả lời

0

Nó phụ thuộc vào những gì bạn đang cố gắng đạt được và trên nền tảng nào?

Dù sao sử dụng thư viện C để tải BMP có thể hoạt động, ví dụ: http://code.google.com/p/libbmp/ hoặc http://freeimage.sourceforge.net/ và thư viện C có thể dễ dàng được gọi từ python, ví dụ: sử dụng ctypes hoặc gói nó như là một mô-đun python.

hoặc bạn có thể biên dịch phiên bản này của PIL https://github.com/sloonz/pil-py3k

+0

Ctypes là khả thi, và tôi đã sử dụng nó và bị mắc kẹt với nó, nhưng nó có xu hướng sản xuất các giải pháp tương đối giòn - nhiều hơn so với C chính nó. Đó là bởi vì việc kiểm tra kiểu có thể tốt hơn với ctypes. Đối với một API rất ổn định, ctypes có thể khá tốt đẹp (đặc biệt nếu bạn muốn nhắm mục tiêu không chỉ cpython mà còn pypy), nhưng cython thực sự có thể tốt hơn cho nhiều thứ nếu bạn sẵn sàng gắn bó với cpython. – user1277476

1

Cổng chung của PIL tới Python 3.x được gọi là "Gối". Ngoài ra tôi sẽ đề nghị thư viện pygame cho các nhiệm vụ đơn giản. Nó là một thư viện, đầy đủ các tính năng để tạo trò chơi - và đọc từ một số định dạng hình ảnh phổ biến nằm trong số đó. Làm việc với Python 3.x là tốt.

10

Trong Python nó chỉ đơn giản có thể được đọc như sau:

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 
+0

Lưu ý, trong SciPy 1.0 [imread (vv) được khấu hao và sẽ bị xóa trong 1.2] (https://docs.scipy.org/doc/scipy/reference/generated/scipy.misc.imsave.html#scipy. misc.imread); SciPy 1.2 sẽ sử dụng 'imageio.imread' – uhoh

0

tôi nhận ra rằng đây là một câu hỏi cũ, nhưng tôi tìm thấy nó khi giải quyết vấn đề này bản thân mình và tôi figured rằng điều này có thể giúp đỡ người khác trong tương lai .

Thật dễ dàng để đọc tệp BMP dưới dạng dữ liệu nhị phân. Tùy thuộc vào cách hỗ trợ rộng và bao nhiêu trường hợp góc bạn cần hỗ trợ tất nhiên.

Dưới đây là một trình phân tích cú pháp đơn giản CHỈ hoạt động cho BMP 1920x1080 24 bit (giống như các tệp được lưu từ MS Paint). Nó sẽ được dễ dàng để mở rộng mặc dù. Nó trích ra các giá trị pixel như một danh sách python như (255, 0, 0, 255, 0, 0, ...) cho một hình ảnh màu đỏ làm ví dụ.

Nếu bạn cần hỗ trợ mạnh mẽ hơn, có thông tin về cách đọc đúng tiêu đề trong câu trả lời cho câu hỏi này: How to read bmp file header in python?. Sử dụng thông tin đó bạn sẽ có thể mở rộng trình phân tích cú pháp đơn giản bên dưới với bất kỳ tính năng nào bạn cần.

Ngoài ra còn có thêm thông tin về định dạng tệp BMP qua tại wikipedia https://en.wikipedia.org/wiki/BMP_file_format nếu bạn cần.

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) 
Các vấn đề liên quan