Skip to content

Commit 69846f2

Browse files
authored
updated for blender 2.8, fixes #11
BIG Thanks to @jmattspartacus for making this happen!
1 parent e82c9de commit 69846f2

File tree

1 file changed

+73
-44
lines changed

1 file changed

+73
-44
lines changed

spritify.py

Lines changed: 73 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
12
# ***** BEGIN GPL LICENSE BLOCK *****
23
#
34
#
@@ -21,8 +22,8 @@
2122
bl_info = {
2223
"name": "Spritify",
2324
"author": "Jason van Gumster (Fweeb)",
24-
"version": (0, 6, 1),
25-
"blender": (2, 66, 0),
25+
"version": (0, 6, 3),
26+
"blender": (2, 80, 0),
2627
"location": "Render > Spritify",
2728
"description": "Converts rendered frames into a sprite sheet once render is complete",
2829
"warning": "Requires ImageMagick",
@@ -31,52 +32,56 @@
3132
"category": "Render"}
3233

3334

34-
import bpy, os, subprocess
35+
import bpy, os, subprocess, math
3536
from bpy.app.handlers import persistent
3637

3738

3839
class SpriteSheetProperties(bpy.types.PropertyGroup):
39-
filepath = bpy.props.StringProperty(
40+
filepath: bpy.props.StringProperty(
4041
name = "Sprite Sheet Filepath",
4142
description = "Save location for sprite sheet (should be PNG format)",
4243
subtype = 'FILE_PATH',
43-
default = os.path.join(bpy.context.user_preferences.filepaths.render_output_directory, "sprites.png"))
44-
quality = bpy.props.IntProperty(
44+
default = os.path.join(bpy.context.preferences.filepaths.render_output_directory, "sprites.png"))
45+
quality: bpy.props.IntProperty(
4546
name = "Quality",
4647
description = "Quality setting for sprite sheet image",
4748
subtype = 'PERCENTAGE',
4849
max = 100,
4950
default = 100)
50-
is_rows = bpy.props.EnumProperty(
51+
is_rows: bpy.props.EnumProperty(
5152
name = "Rows/Columns",
5253
description = "Choose if tiles will be arranged by rows or columns",
5354
items = (('ROWS', "Rows", "Rows"), ('COLUMNS', "Columns", "Columns")),
5455
default = 'ROWS')
55-
tiles = bpy.props.IntProperty(
56+
tiles: bpy.props.IntProperty(
5657
name = "Tiles",
5758
description = "Number of tiles in the chosen direction (rows or columns)",
5859
default = 8)
59-
offset_x = bpy.props.IntProperty(
60+
files : bpy.props.IntProperty(
61+
name = "File count",
62+
description = "Number of files to split sheet into",
63+
default = 1)
64+
offset_x: bpy.props.IntProperty(
6065
name = "Offset X",
6166
description = "Horizontal offset between tiles (in pixels)",
6267
default = 2)
63-
offset_y = bpy.props.IntProperty(
68+
offset_y: bpy.props.IntProperty(
6469
name = "Offset Y",
6570
description = "Vertical offset between tiles (in pixels)",
6671
default = 2)
67-
bg_color = bpy.props.FloatVectorProperty(
72+
bg_color: bpy.props.FloatVectorProperty(
6873
name = "Background Color",
6974
description = "Fill color for sprite backgrounds",
7075
subtype = 'COLOR',
7176
size = 4,
7277
min = 0.0,
7378
max = 1.0,
7479
default = (0.0, 0.0, 0.0, 0.0))
75-
auto_sprite = bpy.props.BoolProperty(
80+
auto_sprite: bpy.props.BoolProperty(
7681
name = "AutoSpritify",
7782
description = "Automatically create a spritesheet when rendering is complete",
7883
default = True)
79-
auto_gif = bpy.props.BoolProperty(
84+
auto_gif: bpy.props.BoolProperty(
8085
name = "AutoGIF",
8186
description = "Automatically create an animated GIF when rendering is complete",
8287
default = True)
@@ -95,36 +100,60 @@ def find_bin_path_windows():
95100

96101
except WindowsError:
97102
return None
98-
103+
104+
print(value)
99105
return value
100106

101107

102108
@persistent
103109
def spritify(scene):
104-
if scene.spritesheet.auto_sprite == True:
105-
print("Making sprite sheet")
106-
# Remove existing spritesheet if it's already there
107-
if os.path.exists(bpy.path.abspath(scene.spritesheet.filepath)):
108-
os.remove(bpy.path.abspath(scene.spritesheet.filepath))
109-
110-
if scene.spritesheet.is_rows == 'ROWS':
111-
tile_setting = str(scene.spritesheet.tiles) + "x"
112-
else:
113-
tile_setting = "x" + str(scene.spritesheet.tiles)
114-
115-
subprocess.call([
116-
"montage",
117-
bpy.path.abspath(scene.render.filepath) + "*", #XXX Assumes the files in the render path are only for the rendered animation
118-
"-tile", tile_setting,
119-
"-geometry", str(scene.render.resolution_x) + "x" + str(scene.render.resolution_y) \
120-
+ "+" + str(scene.spritesheet.offset_x) + "+" + str(scene.spritesheet.offset_y),
121-
"-background", "rgba(" + \
122-
str(scene.spritesheet.bg_color[0] * 100) + "%, " + \
123-
str(scene.spritesheet.bg_color[1] * 100) + "%, " + \
124-
str(scene.spritesheet.bg_color[2] * 100) + "%, " + \
125-
str(scene.spritesheet.bg_color[3]) + ")",
126-
"-quality", str(scene.spritesheet.quality),
127-
bpy.path.abspath(scene.spritesheet.filepath)])
110+
if scene.spritesheet.auto_sprite == True:
111+
print("Making sprite sheet")
112+
# Remove existing spritesheet if it's already there
113+
if os.path.exists(bpy.path.abspath(scene.spritesheet.filepath)):
114+
os.remove(bpy.path.abspath(scene.spritesheet.filepath))
115+
116+
if scene.spritesheet.is_rows == 'ROWS':
117+
tile_setting = str(scene.spritesheet.tiles) + "x"
118+
else:
119+
tile_setting = "x" + str(scene.spritesheet.tiles)
120+
121+
# Preload images
122+
images = []
123+
for dirname, dirnames, filenames in os.walk(bpy.path.abspath(scene.render.filepath)):
124+
for filename in filenames:
125+
images.append(os.path.join(dirname, filename))
126+
127+
# Calc number of images per file
128+
per_file = math.ceil(len(images) / scene.spritesheet.files)
129+
offset = 0
130+
index = 0
131+
132+
#While is faster than for+range
133+
while offset < len(images):
134+
current_images = images[offset:offset+per_file]
135+
filename = scene.spritesheet.filepath
136+
if scene.spritesheet.files > 1:
137+
filename = scene.spritesheet.filepath[:-4] + "-" + str(index) + scene.spritesheet.filepath[-4:]
138+
139+
montage_call = [
140+
"montage",
141+
"-tile", tile_setting,
142+
"-geometry", str(scene.render.resolution_x) + "x" + str(scene.render.resolution_y) \
143+
+ "+" + str(scene.spritesheet.offset_x) + "+" + str(scene.spritesheet.offset_y),
144+
"-background", "rgba(" + \
145+
str(scene.spritesheet.bg_color[0] * 100) + "%, " + \
146+
str(scene.spritesheet.bg_color[1] * 100) + "%, " + \
147+
str(scene.spritesheet.bg_color[2] * 100) + "%, " + \
148+
str(scene.spritesheet.bg_color[3]) + ")",
149+
"-quality", str(scene.spritesheet.quality)
150+
]
151+
montage_call.extend(current_images)
152+
montage_call.append(bpy.path.abspath(filename))
153+
154+
subprocess.call(montage_call)
155+
offset += per_file
156+
index += 1
128157

129158

130159
@persistent
@@ -142,7 +171,7 @@ def gifify(scene):
142171

143172
if bin_path:
144173
convert_path = os.path.join(bin_path, "convert")
145-
174+
146175
subprocess.call([
147176
convert_path,
148177
"-delay", "1x" + str(scene.render.fps),
@@ -215,28 +244,28 @@ def draw(self, context):
215244

216245
layout.prop(context.scene.spritesheet, "filepath")
217246
box = layout.box()
218-
split = box.split(percentage = 0.5)
247+
split = box.split(factor = 0.5)
219248
col = split.column()
220249
col.operator("render.spritify", text = "Generate Sprite Sheet")
221250
col = split.column()
222251
col.prop(context.scene.spritesheet, "auto_sprite")
223-
split = box.split(percentage = 0.5)
252+
split = box.split(factor = 0.5)
224253
col = split.column(align = True)
225254
col.row().prop(context.scene.spritesheet, "is_rows", expand = True)
226255
col.prop(context.scene.spritesheet, "tiles")
227-
sub = col.split(percentage = 0.5)
256+
sub = col.split(factor = 0.5)
228257
sub.prop(context.scene.spritesheet, "offset_x")
229258
sub.prop(context.scene.spritesheet, "offset_y")
230259
col = split.column()
231260
col.prop(context.scene.spritesheet, "bg_color")
232261
col.prop(context.scene.spritesheet, "quality", slider = True)
233262
box = layout.box()
234-
split = box.split(percentage = 0.5)
263+
split = box.split(factor = 0.5)
235264
col = split.column()
236265
col.operator("render.gifify", text = "Generate Animated GIF")
237266
col = split.column()
238267
col.prop(context.scene.spritesheet, "auto_gif")
239-
box.label("Animated GIF uses the spritesheet filepath")
268+
box.label(text="Animated GIF uses the spritesheet filepath")
240269

241270

242271

0 commit comments

Comments
 (0)