Сначала заменяет все ключевые пиксели прозрачными затем обрезает все прозрачные строки и столбцы.
С приведением от http://dl.dropbox.com/u/11931230/Images/converter/data01_00165_3.png
такого к http://dl.dropbox.com/u/11931230/Images/converter/data01_00165_3.jpg
такому работает нормально, с http://dl.dropbox.com/u/11931230/Images/converter/OVE1a.jpg
более сложными начинаются http://dl.dropbox.com/u/11931230/Images/converter/OVE1a.png
косяки.
К тому же работает медленно так как маска строится попиксельно, да и вычисление прямоугольника обрезки тоже.
Подскажите пожалуйста как можно конвертировать более аккуратно, и желательно, быстро.
import os, sys, Image
path = os.path.realpath(os.path.dirname(sys.argv[0]))
for fname in os.listdir(path):
if fname.lower().endswith(('.bmp','.jpg',".png")):
outfile = fname[:-4] + ".png"
im = Image.open(fname)
print "Old: %s - %dx%d"%(fname,im.size[0],im.size[1])
#convert to png
im = im.convert('RGBA')
source = im.split()
colorkey = im.getpixel((im.size[0]-1,im.size[1]-1))
mask = Image.new("RGBA", (im.size[0], im.size[1]))
for x in xrange(im.size[0]):
for y in xrange(im.size[1]):
if im.getpixel((x,y)) == colorkey:
mask.putpixel((x,y),(0,0,0,255))
else:
mask.putpixel((x,y),(255,255,255,0))
#mask.save("_file.png")
# break
# process the alpha band fully transparent
out = source[3].point(lambda i: i * 0.0)
# paste the processed band back, but only to selected pixels
source[3].paste(out, None, mask)
# build a new multiband image
im = Image.merge(im.mode, source)
#crop rectangle
box = [0,0,im.size[0],im.size[1]]
border = []
#search non-transparent pixels
for x in xrange(im.size[0]):
for y in xrange(im.size[1]):
p = im.getpixel((x,y))
if p[3] is not 0:
border.append(y)
if box[0] is 0:
box[0] = x
else:
box[2] = x
break
box[1] = min(border)
im = im.crop(box)
border = []
im = im.transpose(Image.FLIP_TOP_BOTTOM)
#lower boundary
for x in xrange(im.size[0]):
for y in xrange(im.size[1]):
p = im.getpixel((x,y))
if p[3] is not 0:
border.append(y)
box = [0,0,im.size[0],im.size[1]]
box[1] = min(border)
im = im.crop(box)
im = im.transpose(Image.FLIP_TOP_BOTTOM)
path = os.path.split(os.path.realpath(outfile))
outfile = os.path.join(path[0],"converted",path[1])
if os.path.exists(os.path.join(path[0],"converted")):
im.save(outfile)
else:
#get dir name
path = os.path.realpath(outfile)
dir = os.path.split(path)[0]
if not os.path.exists(dir):
os.makedirs(dir)
im.save(outfile)
print "New: %s - %dx%d"%(fname,im.size[0],im.size[1])
print "Done"
Сам скрипт в нескольких вариантах.