5061
by Holger Rapp
Cleaned the new crop animation script up a bit. Made it more conform to PEP8 |
1 |
#!/usr/bin/env python
|
5060
by Timo Wingender
Add a new script to crop animations |
2 |
# -*- coding: utf-8 -*-
|
3 |
||
4 |
# Copyright (C) 2010 by the Widelands Development Team
|
|
5 |
#
|
|
6 |
# This program is free software; you can redistribute it and/or
|
|
7 |
# modify it under the terms of the GNU General Public License
|
|
8 |
# as published by the Free Software Foundation; either version 2
|
|
9 |
# of the License, or (at your option) any later version.
|
|
10 |
#
|
|
11 |
#
|
|
5061
by Holger Rapp
Cleaned the new crop animation script up a bit. Made it more conform to PEP8 |
12 |
# This script takes one or more conf files on the command line.
|
13 |
# It reads [idle] and [working] sections from these files and
|
|
5060
by Timo Wingender
Add a new script to crop animations |
14 |
# take the pics= and playercolor= lines from these sections.
|
15 |
#
|
|
5061
by Holger Rapp
Cleaned the new crop animation script up a bit. Made it more conform to PEP8 |
16 |
#
|
17 |
#
|
|
5060
by Timo Wingender
Add a new script to crop animations |
18 |
#
|
19 |
||
20 |
import os |
|
21 |
import re |
|
22 |
import sys |
|
5061
by Holger Rapp
Cleaned the new crop animation script up a bit. Made it more conform to PEP8 |
23 |
|
5060
by Timo Wingender
Add a new script to crop animations |
24 |
from PIL import Image |
25 |
||
5061
by Holger Rapp
Cleaned the new crop animation script up a bit. Made it more conform to PEP8 |
26 |
"""
|
27 |
This script takes a list of conf files as arguments and crops
|
|
28 |
the correponding animations to their proper size
|
|
29 |
||
30 |
usage:
|
|
31 |
find -type f -name conf -exec crop_animation.py {} \;
|
|
32 |
"""
|
|
33 |
||
8201
by GunChleoc
Fetched translations and updated catalogues. |
34 |
|
5060
by Timo Wingender
Add a new script to crop animations |
35 |
def crop_images(basepath, section): |
8201
by GunChleoc
Fetched translations and updated catalogues. |
36 |
"""crop_images does the work of actually cropping the animation pictures
|
37 |
from a conf section.
|
|
38 |
||
39 |
The first parameter basepath is the directory in which the conf file
|
|
40 |
was. The second parameter section is a dictionary with contains the
|
|
41 |
important contents of the section from the conf file
|
|
42 |
||
5061
by Holger Rapp
Cleaned the new crop animation script up a bit. Made it more conform to PEP8 |
43 |
"""
|
44 |
# two empty lists. The first for the animation pictures
|
|
8201
by GunChleoc
Fetched translations and updated catalogues. |
45 |
list = [] |
5061
by Holger Rapp
Cleaned the new crop animation script up a bit. Made it more conform to PEP8 |
46 |
# the second one for the player color masks
|
8201
by GunChleoc
Fetched translations and updated catalogues. |
47 |
list_pc = [] |
5061
by Holger Rapp
Cleaned the new crop animation script up a bit. Made it more conform to PEP8 |
48 |
|
8201
by GunChleoc
Fetched translations and updated catalogues. |
49 |
basepath = basepath + '/' |
5061
by Holger Rapp
Cleaned the new crop animation script up a bit. Made it more conform to PEP8 |
50 |
|
51 |
if 'pics' in section: |
|
8201
by GunChleoc
Fetched translations and updated catalogues. |
52 |
filepattern = section['pics'] |
5061
by Holger Rapp
Cleaned the new crop animation script up a bit. Made it more conform to PEP8 |
53 |
else: |
8201
by GunChleoc
Fetched translations and updated catalogues. |
54 |
filepattern = section['dirpics'] |
5061
by Holger Rapp
Cleaned the new crop animation script up a bit. Made it more conform to PEP8 |
55 |
|
8201
by GunChleoc
Fetched translations and updated catalogues. |
56 |
# TODO(sirver): playercolor is never used in the conf files anymore.
|
57 |
# remove this.
|
|
58 |
use_playercolor = False |
|
5061
by Holger Rapp
Cleaned the new crop animation script up a bit. Made it more conform to PEP8 |
59 |
if 'playercolor' in section and \ |
8201
by GunChleoc
Fetched translations and updated catalogues. |
60 |
section['playercolor'].upper().strip() == 'TRUE': |
61 |
use_playercolor = True |
|
5061
by Holger Rapp
Cleaned the new crop animation script up a bit. Made it more conform to PEP8 |
62 |
|
63 |
# replace the placeholders ?? and !! by a .
|
|
8201
by GunChleoc
Fetched translations and updated catalogues. |
64 |
filepattern = filepattern.replace(r".", r"\.") |
65 |
filepattern = filepattern.replace(r"??", r"[0-9][0-9]") |
|
66 |
filepattern = filepattern.replace(r"!!", r"(e|w|sw|se|nw|ne)") |
|
5061
by Holger Rapp
Cleaned the new crop animation script up a bit. Made it more conform to PEP8 |
67 |
# The end of the pattern is the end of the filename
|
8201
by GunChleoc
Fetched translations and updated catalogues. |
68 |
filepattern += '$' |
5061
by Holger Rapp
Cleaned the new crop animation script up a bit. Made it more conform to PEP8 |
69 |
|
70 |
# create a pattern for the playercolor masks
|
|
8201
by GunChleoc
Fetched translations and updated catalogues. |
71 |
filepattern_pc = filepattern.rpartition('\.') |
72 |
filepattern_pc = filepattern_pc[0] + '_pc\\.' + filepattern_pc[2] |
|
5061
by Holger Rapp
Cleaned the new crop animation script up a bit. Made it more conform to PEP8 |
73 |
|
5071
by Timo Wingender
fix another bug in crop animation script: correct the file pattern and make it more robust |
74 |
# print filepattern
|
75 |
# print filepattern_pc
|
|
5061
by Holger Rapp
Cleaned the new crop animation script up a bit. Made it more conform to PEP8 |
76 |
|
77 |
for filename in os.listdir(basepath): |
|
78 |
if re.match(filepattern, filename): |
|
79 |
list.append(filename) |
|
80 |
if use_playercolor and re.match(filepattern_pc, filename): |
|
81 |
list_pc.append(filename) |
|
82 |
||
83 |
# Now we have two list which contains the animation pictures and the
|
|
84 |
# playercolor mask
|
|
85 |
||
8201
by GunChleoc
Fetched translations and updated catalogues. |
86 |
# print list
|
87 |
# print list_pc
|
|
5061
by Holger Rapp
Cleaned the new crop animation script up a bit. Made it more conform to PEP8 |
88 |
|
8201
by GunChleoc
Fetched translations and updated catalogues. |
89 |
if len(list) < 1: |
90 |
return 'error' # we found no pictures |
|
5061
by Holger Rapp
Cleaned the new crop animation script up a bit. Made it more conform to PEP8 |
91 |
|
92 |
# Now open the first picture, get the size and validate the size
|
|
8201
by GunChleoc
Fetched translations and updated catalogues. |
93 |
im = Image.open(basepath + list[0]) |
94 |
size = im.size |
|
95 |
if size[0] < 1 or size[1] < 1: |
|
96 |
print '*** ERROR ***: image has size 0' |
|
97 |
return 'error' |
|
5061
by Holger Rapp
Cleaned the new crop animation script up a bit. Made it more conform to PEP8 |
98 |
# Set a first boundingbox to crop away the maximum from the picture
|
8201
by GunChleoc
Fetched translations and updated catalogues. |
99 |
crop = [size[0], size[1], 0, 0] |
5061
by Holger Rapp
Cleaned the new crop animation script up a bit. Made it more conform to PEP8 |
100 |
|
101 |
# Now go through all picture of the animation and get the boundingbox
|
|
102 |
for file in list: |
|
8201
by GunChleoc
Fetched translations and updated catalogues. |
103 |
# print basepath+file
|
104 |
im = Image.open(basepath + file) |
|
105 |
# im.show()
|
|
106 |
bb = im.getbbox() |
|
107 |
# print "Bounding box for " + file + ": ",
|
|
108 |
# print bb
|
|
5061
by Holger Rapp
Cleaned the new crop animation script up a bit. Made it more conform to PEP8 |
109 |
|
110 |
# Here the boundingbox is adjusted. It's only set it to crop away less
|
|
111 |
# of the picture
|
|
8201
by GunChleoc
Fetched translations and updated catalogues. |
112 |
if bb[0] < crop[0]: |
113 |
crop[0] = bb[0] |
|
114 |
if bb[1] < crop[1]: |
|
115 |
crop[1] = bb[1] |
|
116 |
if bb[2] > crop[2]: |
|
117 |
crop[2] = bb[2] |
|
118 |
if bb[3] > crop[3]: |
|
119 |
crop[3] = bb[3] |
|
5061
by Holger Rapp
Cleaned the new crop animation script up a bit. Made it more conform to PEP8 |
120 |
# Assure that the size of all images of the animation is the same
|
8201
by GunChleoc
Fetched translations and updated catalogues. |
121 |
if im.size != size: |
122 |
print '*** Error *** Frame size changed', basepath, ' ', file |
|
123 |
return 'error' |
|
5061
by Holger Rapp
Cleaned the new crop animation script up a bit. Made it more conform to PEP8 |
124 |
|
125 |
# Now we have a common boundingbox of all images of the animation
|
|
126 |
||
8201
by GunChleoc
Fetched translations and updated catalogues. |
127 |
# print crop,
|
128 |
# print " ",
|
|
129 |
# print size,
|
|
130 |
if crop[0] > 0 or crop[1] > 0 or crop[2] < size[0] or crop[3] < size[1]: |
|
5061
by Holger Rapp
Cleaned the new crop animation script up a bit. Made it more conform to PEP8 |
131 |
# We have somethin to crop
|
8201
by GunChleoc
Fetched translations and updated catalogues. |
132 |
rect = (crop[0], crop[1], crop[2], crop[3]) |
133 |
print 'crop images', filepattern, filepattern_pc |
|
5061
by Holger Rapp
Cleaned the new crop animation script up a bit. Made it more conform to PEP8 |
134 |
|
135 |
# If playercolor was true in the config file add the playercolor masks
|
|
136 |
# tho the list
|
|
137 |
if use_playercolor: |
|
138 |
list += list_pc |
|
139 |
||
8201
by GunChleoc
Fetched translations and updated catalogues. |
140 |
# print list
|
5061
by Holger Rapp
Cleaned the new crop animation script up a bit. Made it more conform to PEP8 |
141 |
|
142 |
# Now go through all images (include playercolor mask if set) and crop
|
|
143 |
# them
|
|
144 |
for file in list: |
|
8201
by GunChleoc
Fetched translations and updated catalogues. |
145 |
im = Image.open(basepath + file) |
146 |
# print "crop", basepath+file, " ",im.size, rect
|
|
147 |
im = im.crop(rect) |
|
5061
by Holger Rapp
Cleaned the new crop animation script up a bit. Made it more conform to PEP8 |
148 |
# Images in paletted mode have to be handled differently. If they
|
149 |
# are saved without the option the transparency is lost
|
|
8201
by GunChleoc
Fetched translations and updated catalogues. |
150 |
if(im.mode == 'P'): |
151 |
im.save(basepath + file, quality=100, transparency=0) |
|
5061
by Holger Rapp
Cleaned the new crop animation script up a bit. Made it more conform to PEP8 |
152 |
else: |
8201
by GunChleoc
Fetched translations and updated catalogues. |
153 |
im.save(basepath + file, quality=100) |
5061
by Holger Rapp
Cleaned the new crop animation script up a bit. Made it more conform to PEP8 |
154 |
# If this function cropped something it returns a tupple containing
|
155 |
# the crop rect
|
|
156 |
return rect |
|
157 |
else: |
|
8201
by GunChleoc
Fetched translations and updated catalogues. |
158 |
# print "nothing to do for", filepattern, filepattern_pc
|
159 |
return 'unchanged' |
|
5061
by Holger Rapp
Cleaned the new crop animation script up a bit. Made it more conform to PEP8 |
160 |
|
161 |
||
5060
by Timo Wingender
Add a new script to crop animations |
162 |
def read_conffile(filename): |
8201
by GunChleoc
Fetched translations and updated catalogues. |
163 |
"""read_conf reads a configfile and searches for sections which contain
|
164 |
pic= or dirpic=.
|
|
165 |
||
166 |
Such section are added to a list. For every of these sections the
|
|
167 |
function crop_images() is called. of crop_images did not return
|
|
168 |
"error" or "unchanged" the hotspot in the conf file is adjusted by
|
|
169 |
the top and left values of the crop rectangle. The parameter to
|
|
170 |
this function is the conf file
|
|
171 |
||
172 |
"""
|
|
173 |
print 'read ' + filename |
|
5061
by Holger Rapp
Cleaned the new crop animation script up a bit. Made it more conform to PEP8 |
174 |
|
175 |
# We read the complete file to a list of lines
|
|
176 |
f = open(filename) |
|
177 |
lines = f.readlines() |
|
178 |
f.close() |
|
179 |
||
8201
by GunChleoc
Fetched translations and updated catalogues. |
180 |
basepath = os.path.split(filename) |
181 |
basepath = basepath[0] |
|
182 |
# print basepath
|
|
5061
by Holger Rapp
Cleaned the new crop animation script up a bit. Made it more conform to PEP8 |
183 |
|
184 |
# section_begin track where the current section began
|
|
8201
by GunChleoc
Fetched translations and updated catalogues. |
185 |
section_begin = 0 |
5061
by Holger Rapp
Cleaned the new crop animation script up a bit. Made it more conform to PEP8 |
186 |
# insection a list of matching section is saved
|
8201
by GunChleoc
Fetched translations and updated catalogues. |
187 |
sections = [] |
5061
by Holger Rapp
Cleaned the new crop animation script up a bit. Made it more conform to PEP8 |
188 |
# i counts the lines
|
8201
by GunChleoc
Fetched translations and updated catalogues. |
189 |
i = 0 |
5061
by Holger Rapp
Cleaned the new crop animation script up a bit. Made it more conform to PEP8 |
190 |
# section is a dictionary where the contents of the current section are
|
191 |
# stored
|
|
8201
by GunChleoc
Fetched translations and updated catalogues. |
192 |
section = {} |
5061
by Holger Rapp
Cleaned the new crop animation script up a bit. Made it more conform to PEP8 |
193 |
|
194 |
# First go through all lines and identify relevant sections
|
|
195 |
for line in lines: |
|
8201
by GunChleoc
Fetched translations and updated catalogues. |
196 |
line = line.split('#') |
197 |
line = line[0].strip(' \r\n\t') |
|
198 |
if re.match(r"\[[a-zA-Z0-9]*\]", line): |
|
199 |
# print "*** section begin"
|
|
200 |
if 'pics' in section or 'dirpics' in section: |
|
201 |
sections.append((section_begin, i - 1, section)) |
|
202 |
section_begin = i |
|
203 |
section = {'name': 'test'} |
|
5061
by Holger Rapp
Cleaned the new crop animation script up a bit. Made it more conform to PEP8 |
204 |
if re.match(r"(pics=|dirpics=|hotspot=|playercolor=)", line): |
8201
by GunChleoc
Fetched translations and updated catalogues. |
205 |
keyval = line.split('=') |
206 |
section[keyval[0]] = keyval[1] |
|
207 |
i += 1 |
|
208 |
if 'pics' in section or 'dirpics' in section: |
|
209 |
pic_section = False |
|
210 |
sections.append((section_begin, i - 1, section)) |
|
5061
by Holger Rapp
Cleaned the new crop animation script up a bit. Made it more conform to PEP8 |
211 |
|
212 |
# Now use the information gatherd above to crop the images
|
|
213 |
for section in sections: |
|
8201
by GunChleoc
Fetched translations and updated catalogues. |
214 |
# print section
|
5061
by Holger Rapp
Cleaned the new crop animation script up a bit. Made it more conform to PEP8 |
215 |
# Crop the animation ...
|
216 |
ret = crop_images(basepath, section[2]) |
|
217 |
||
218 |
# See if we cropped images
|
|
8201
by GunChleoc
Fetched translations and updated catalogues. |
219 |
if ret != 'error' and ret != 'unchanged': |
220 |
if (ret[0] > 0 or ret[1] > 0) and 'hotspot' in section[2]: |
|
5061
by Holger Rapp
Cleaned the new crop animation script up a bit. Made it more conform to PEP8 |
221 |
# Somethin was cropped from top or left, so adjust the hotspot
|
8201
by GunChleoc
Fetched translations and updated catalogues. |
222 |
print 'change hotspot', ret |
223 |
oldhs = section[2]['hotspot'].split(' ') |
|
224 |
newhs = (int(oldhs[0]) - ret[0], int(oldhs[1]) - ret[1]) |
|
225 |
# print oldhs, newhs
|
|
5066
by Timo Wingender
small fix to crop animation script: now adjust all hotspots for an animation |
226 |
# search all section which use this animation
|
227 |
for sec in sections: |
|
8201
by GunChleoc
Fetched translations and updated catalogues. |
228 |
if 'pics' in section[2]: |
229 |
fname = section[2]['pics'] |
|
5066
by Timo Wingender
small fix to crop animation script: now adjust all hotspots for an animation |
230 |
else: |
8201
by GunChleoc
Fetched translations and updated catalogues. |
231 |
fname = section[2]['dirpics'] |
232 |
if ('pics' in sec[2] and sec[2]['pics'] == fname) or \ |
|
233 |
('dirpics' in sec[2] and sec[2]['dirpics'] == fname): |
|
6509.1.11
by Holger Rapp
Removed playercolor key. Use playercolor when there are _pc.png files for this animation automatically. |
234 |
# Simply go through the lines of the section and
|
235 |
# search for hotspot= if found replace the line. It
|
|
5066
by Timo Wingender
small fix to crop animation script: now adjust all hotspots for an animation |
236 |
# will be written to the conf file a the end
|
8201
by GunChleoc
Fetched translations and updated catalogues. |
237 |
for i in range(sec[0], sec[1] + 1): |
238 |
# print i,
|
|
239 |
# print lines[i],
|
|
5066
by Timo Wingender
small fix to crop animation script: now adjust all hotspots for an animation |
240 |
if re.match(r"hotspot=", lines[i]): |
8201
by GunChleoc
Fetched translations and updated catalogues. |
241 |
lines[i] = 'hotspot=%u %u\n' % ( |
242 |
newhs[0], newhs[1]) |
|
243 |
# print i, lines[i],
|
|
5061
by Holger Rapp
Cleaned the new crop animation script up a bit. Made it more conform to PEP8 |
244 |
|
245 |
# Now we write back the conf file from our list of lines
|
|
8201
by GunChleoc
Fetched translations and updated catalogues. |
246 |
f = open(filename, 'w') |
5061
by Holger Rapp
Cleaned the new crop animation script up a bit. Made it more conform to PEP8 |
247 |
f.writelines(lines) |
248 |
f.close() |
|
249 |
||
250 |
||
251 |
def main(): |
|
8201
by GunChleoc
Fetched translations and updated catalogues. |
252 |
"""This is the main function.
|
253 |
||
254 |
It calls read_conffile() for every file given to this program
|
|
255 |
||
256 |
"""
|
|
257 |
if len(sys.argv) <= 1: |
|
258 |
print 'Usage: ' + sys.argv[0] + ' conf-files' |
|
5061
by Holger Rapp
Cleaned the new crop animation script up a bit. Made it more conform to PEP8 |
259 |
sys.exit() |
260 |
||
261 |
for file in sys.argv[1:]: |
|
262 |
if os.path.isfile(file): |
|
263 |
read_conffile(file) |
|
264 |
else: |
|
8201
by GunChleoc
Fetched translations and updated catalogues. |
265 |
print '*** WARNING ***: ' + file + ' is not a file' |
5061
by Holger Rapp
Cleaned the new crop animation script up a bit. Made it more conform to PEP8 |
266 |
|
267 |
if __name__ == '__main__': |
|
268 |
main() |