Tag Archives: PIL

Create a warcraft world map by PIL

通过使用Python Image Library创建魔兽世界地图
代码如下

#coding: utf-8
import _mysql as mysql
import MySQLdb
import os, io, re, math;
import Image

class WorldMaps(object):
def __init__(self, base, output):
self._basedir = base
self._output = output

self.connectMysql()
self.cacheMaps()

def connectMysql(self):
self.db = mysql.connect(host=”127.0.0.1″, user=”root”, passwd=””, db=”wowdb_ctm”)
self.db.query(“SET NAMES UTF8”)

#cache maps metadata from WorldMapArea.dbc
def cacheMaps(self):
self.MAPS_INFO = {}
sql = “SELECT ID, Map, AreaTable, Icon FROM worldmapareadbc”
self.db.query(sql)
results = self.db.store_result()
data = results.fetch_row()

while (data):
data, = data;
self.MAPS_INFO[int(data[0])] = {
“mapid” : data[1],
“areaid” : data[2],
“mapfilename” : data[3]
}
#fetch now
data = results.fetch_row()

def GetNumberOfDetailTiles(self, dirname, mapfilename):
numOnDetailTiles = 0;
for filename in os.listdir(dirname):
if (re.match(mapfilename+”(\d+)”, filename)):
numOnDetailTiles = numOnDetailTiles + 1;
return numOnDetailTiles;

def GetMapInfo(self, mapid):
mapid = int(mapid)
mapinfo = self.MAPS_INFO[mapid]
mapfilename = mapinfo[“mapfilename”]
return mapfilename, self._basedir + “/” + mapfilename + “/”

def GetMapOverlays(self, mapid):
overlays = []
sql = “SELECT Path, Width, Height, `Left`, `Top` FROM worldmapoverlaydbc WHERE ZoneId = ” + str(mapid);
self.db.query(sql);
results = self.db.store_result();
data = results.fetch_row();
while data:
data, = data
overlays.append({
“path” : data[0],
“width” : int(data[1]),
“height”: int(data[2]),
“left” : int(data[3]),
“top” : int(data[4])
});

data = results.fetch_row();

return overlays

def createWorldMap(self, mapid):
mapfilename, dirname = self.GetMapInfo(mapid)

numOnDetailTiles = self.GetNumberOfDetailTiles(dirname, mapfilename);
texs = {};

#map standard size: 1002 * 668
new_image = Image.new(“RGB”, (1002, 668));
x = 0;
y = 1;
for i in range (1, numOnDetailTiles+1):
texName = dirname + “/” + mapfilename + str(i) + “.png”
# x x x x
# x x x x
# x x x x
texs[i] = Image.open(texName);
x = x + 1;
#print x, y
new_image.paste(texs[i], (x * 256 – 256, y * 256 – 256));
if x == 4:
y = y + 1
x = 0;

#sec, get overlays, and paste
overlays = self.GetMapOverlays(mapid)
textureCount = 0
for overlayinfo in overlays:
textureName = overlayinfo[“path”];
textureWidth = overlayinfo[“width”];
textureHeight = overlayinfo[“height”];
offsetX = overlayinfo[“left”];
offsetY = overlayinfo[“top”];
#print textureWidth, textureHeight, textureName

if (textureName and textureName != “”):
numTexturesWide = math.ceil(float(textureWidth) / float(256))
numTexturesTall = math.ceil(float(textureHeight) / float(256))
#print textureWidth, textureHeight, textureName, numTexturesWide, numTexturesTall
neededTextures = int(textureCount + (numTexturesWide * numTexturesTall))

texturePixelWidth = 0
texturePixelHeight = 0
textureFileWidth = 0
textureFileHeight = 0
for j in range(1, int(numTexturesTall) + 1):
if (j < numTexturesTall): texturePixelHeight = 256 textureFileHeight = 256 else: texturePixelHeight = textureHeight % 256; if (texturePixelHeight == 0): texturePixelHeight = 256 textureFileHeight = 16 while textureFileHeight < texturePixelHeight: textureFileHeight = textureFileHeight * 2for k in range(1, int(numTexturesWide) + 1): textureCount = textureCount + 1 if (k < numTexturesWide): texturePixelWidth = 256 textureFileWidth = 256 else: texturePixelWidth = textureWidth % 256 if (texturePixelWidth == 0): texturePixelWidth = 256 textureFileWidth = 256 while textureFileWidth < texturePixelWidth: textureFileWidth = textureFileWidth * 2_textureName = textureName + str(int((( j - 1) * numTexturesWide) + k)) + ".png"; texture = Image.open(dirname + "/" + _textureName); new_image.paste(texture, ( (offsetX + (256 * (k - 1))) , ((offsetY + (256 * (j - 1)))) ), texture ); new_image.save( self._output + "/" + str(mapid) + ".png"); [/python]生成的效果图: