Hi folks,
I wanted some functionality to arrange tile exports in columns so I modified @dacap’s gist above. Thought I’d share. I’ll leave the planning on what features the built-in implementation should have to others.
Dialog and test looks like this
Two sample results look like these:
3 column export beginning at index 1.
4 column export beginning at index 0.
(Notice the tiles are not properly ordered in the original.)
local defaults = {
filePath = "",
startIndex = 0,
count = 256,
columns = 8
}
local dlg = Dialog { title = "Export Tileset" }
dlg:file {
id = "filePath",
label = "Path:",
save = true,
focus = false,
filename = defaults.filePath
}
dlg:newrow { always = false }
dlg:slider {
id = "startIndex",
label = "Start:",
min = 0,
max = 255,
value = defaults.startIndex
}
dlg:newrow { always = false }
dlg:slider {
id = "count",
label = "Count:",
min = 1,
max = 256,
value = defaults.count
}
dlg:newrow { always = false }
dlg:slider {
id = "columns",
label = "Columns:",
min = 1,
max = 32,
value = defaults.columns
}
dlg:newrow { always = false }
dlg:button {
id = "confirm",
text = "&OK",
focus = false,
onclick = function()
-- Original export script:
-- https://gist.github.com/dacap/9df368ba276a45048dc85f96b23ea818
-- Discussion on tileset export functionality:
-- https://community.aseprite.org/t/saving-tilesets/9398/22
-- For determining undocumented object methods:
-- https://stackoverflow.com/questions/2620377/lua-reflection-get-list-of-functions-fields-on-an-object
local version = app.version
if version.major >= 1 and version.minor >= 3 and TilesetMode then
local sprite = app.activeSprite
if sprite then
local layer = app.activeLayer
if layer then
local isTileMap = layer.isTilemap
if isTileMap then
local tileSet = layer.tileset
-- for key, value in pairs(getmetatable(tileSet)) do
-- print(key, value)
-- end
local tileCount = #tileSet
local grid = tileSet.grid
local tileDim = grid.tileSize
local tileWidth = tileDim.width
local tileHeight = tileDim.height
local args = dlg.data
local filePath = args.filePath or defaults.filePath
local startIndex = args.startIndex or defaults.startIndex
local count = args.count or defaults.count
local columns = args.columns or defaults.columns
local si = math.min(tileCount - 1, math.max(0, startIndex))
local vc = math.min(tileCount - si, math.max(1, count))
local imgWidth = tileWidth * columns
local imgHeight = tileHeight * math.ceil(vc / columns)
-- Original script either copies or acquires a reference
-- to the image specification. Not sure if that makes a
-- difference to new image; ImageSpec also tracks the
-- transparentColor.
-- https://github.com/aseprite/api/blob/main/api/imagespec.md#imagespec
local image = Image(imgWidth, imgHeight, sprite.colorMode)
for i = 0, vc - 1, 1 do
local x = i % columns
local y = i // columns
local xScaled = x * tileWidth
local yScaled = y * tileHeight
local tile = tileSet:getTile(si + i)
image:drawImage(tile, xScaled, yScaled)
end
if #filePath > 0 then
image:saveAs(filePath)
dlg:close()
else
app.alert("Invalid file path (empty String).")
end
else
app.alert("The active layer is not a tilemap.")
end
else
app.alert("There is no active layer.")
end
else
app.alert("There is no active sprite.")
end
else
app.alert("Version 1.3 or later is required to use tilemaps.")
end
end
}
dlg:button {
id = "cancel",
text = "&CANCEL",
onclick = function()
dlg:close()
end
}
dlg:show { wait = false }
Probably there are edge cases that will catch this out.
Thanks! Best,
Jeremy