當你沒有給出的「最好」的含義指示,我會想它的意思是「用更簡潔的代碼」。
比方說,你有以下數據:
from collections import Sequence
import operator
assert(type(MIN_AREA) is int)
assert(type(MAX_AREA) is int)
assert(type(width) is int)
assert(type(height) is int)
assert(instanceof(data, Sequence))
assert(len(data) == width * height)
assert(MAX_AREA >= 2 * MIN_AREA)
(在MIN和MAX方面的條件是必要的這個工作)
有一些案件中,這不可能是與任何算法進行,例如在分離的4和8之間
瓦片的3×3的圖像假設數據由行存儲(如在例如PNM規範)。
def split_(seq, size):
return [seq[i:i+size] for i in range(0,len(seq),size)]
tiles = list()
if width >= MIN_AREA:
# each row is subdivided into multiple tiles
tile_width = width/(width/MIN_AREA) # integral division
rows = split_(data, width)
row_tiles = [split_(row, tile_width) for row in rows]
tiles = reduce(operator.add, row_tiles)
elif width < MIN_AREA:
# each tile is composed of rows
min_tile_height = int(MIN_AREA/width) + 1
tile_height = height/(height/min_tile_height)
tile_size = tile_height * width
tiles = split_(data, tile_size)
if len(tiles[-1]) < MIN_AREA:
if (tile_height > 2):
tiles[-2] += tiles[-1]
del tiles[-1]
else: # tile_height == 2, the case 1 don't pass here
# special case, we need to split vertically the last three rows
# if the width was 3 too we have a problem but then if we are here
# then MIN_AREA was 4, and MAX_AREA was 8, and the rows are >= 5
if width > 3:
last_three_rows = split_(tiles[-2] + tiles[-1], width)
tiles[-2] = reduce(operator.add,[row[:width/2] for row in last_three_rows])
tiles[-1] = reduce(operator.add,[row[width/2:] for row in last_three_rows])
else: # width = 3 and MIN_AREA = 4
last_five_rows = reduce(operator.add, tiles[-3:])
three_columns = [last_five_rows[i::3] for i in range(3)]
tiles[-3:] = three_columns
只要記住,在你得到兩個或三個片並排側,和所有其它堆疊上面他們最後的情況下(或低於,不同的地方是一排「0」)。
如果你需要存儲比原始像素數據更多,只需調整瓦的創建過程。
+1:使用PIL將使您的生活更容易使用瓷磚。如果你正在爲遊戲構建一個tile引擎,pygame也可能值得一看。 – ChristopheD 2010-08-18 09:42:53
嗨,感謝您的建議,然而,分裂成瓦片的原因是這樣的圖像可以通過以太網鏈接發送小包和重建在另一端 – mikip 2010-08-18 09:49:30