Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>Save your files as uncompressed 24-bit BMPs. These store pixel data in a very regular way. Check out the "Image Data" portion of this diagram from <a href="http://en.wikipedia.org/wiki/BMP_file_format" rel="nofollow noreferrer">Wikipedia</a>. Note that most of the complexity in the diagram is just from the headers:</p> <p><img src="https://upload.wikimedia.org/wikipedia/commons/c/c4/BMPfileFormat.png" alt="BMP file format"></p> <p>For example, let's say you are storing this image (here shown zoomed in):</p> <p><img src="https://upload.wikimedia.org/wikipedia/commons/thumb/e/e8/Bmp_format.svg/134px-Bmp_format.svg.png" alt="2x2 square image"></p> <p>This is what the pixel data section looks like, if it's stored as a 24-bit uncompressed BMP. Note that the data is stored bottom-up, for some reason, and in BGR form instead of RGB, so the first line in the file is the bottom-most line of the image, the second line is the second-bottom-most, etc:</p> <pre><code>00 00 FF FF FF FF 00 00 FF 00 00 00 FF 00 00 00 </code></pre> <p>That data is explained as follows:</p> <pre><code> | First column | Second Column | Padding -----------+----------------+-----------------+----------- Second Row | 00 00 FF | FF FF FF | 00 00 -----------+----------------+-----------------+----------- First Row | FF 00 00 | 00 FF 00 | 00 00 -----------+----------------+-----------------+----------- </code></pre> <p>or:</p> <pre><code> | First column | Second Column | Padding -----------+----------------+-----------------+----------- Second Row | red | white | 00 00 -----------+----------------+-----------------+----------- First Row | blue | green | 00 00 -----------+----------------+-----------------+----------- </code></pre> <p>The padding is there to pad the row size to a multiple of 4 bytes.</p> <hr> <p>So, all you have to do is implement a reader for this particular file format, and then calculate the byte offset of where you have to start and stop reading each row:</p> <pre><code>def calc_bytes_per_row(width, bytes_per_pixel): res = width * bytes_per_pixel if res % 4 != 0: res += 4 - res % 4 return res def calc_row_offsets(pixel_array_offset, bmp_width, bmp_height, x, y, row_width): if x + row_width &gt; bmp_width: raise ValueError("This is only for calculating offsets within a row") bytes_per_row = calc_bytes_per_row(bmp_width, 3) whole_row_offset = pixel_array_offset + bytes_per_row * (bmp_height - y - 1) start_row_offset = whole_row_offset + x * 3 end_row_offset = start_row_offset + row_width * 3 return (start_row_offset, end_row_offset) </code></pre> <p>Then you just have to process the proper byte offsets. For example, say you want to read the 400x400 chunk starting at position 500x500 in a 10000x10000 bitmap:</p> <pre><code>def process_row_bytes(row_bytes): ... some efficient way to process the bytes ... bmpf = open(..., "rb") pixel_array_offset = ... extract from bmp header ... bmp_width = 10000 bmp_height = 10000 start_x = 500 start_y = 500 end_x = 500 + 400 end_y = 500 + 400 for cur_y in xrange(start_y, end_y): start, end = calc_row_offsets(pixel_array_offset, bmp_width, bmp_height, start_x, cur_y, end_x - start_x) bmpf.seek(start) cur_row_bytes = bmpf.read(end - start) process_row_bytes(cur_row_bytes) </code></pre> <p>Note that it's important how you process the bytes. You can probably do something clever using PIL and just dumping the pixel data into it but I'm not entirely sure. If you do it in an inefficient manner then it might not be worth it. If speed is a huge concern, you might consider writing it with <a href="http://www.cosc.canterbury.ac.nz/greg.ewing/python/Pyrex/" rel="nofollow noreferrer">pyrex</a> or implementing the above in C and just calling it from Python.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload