I’m building an aseprite extension for exporting to puzzlescript. It turns parts of images into palettized strings; for example, it turns this image:
into this string:
chicken
#fff1e8 #83769c #ffa300 #be1250
.000.
.0102
00003
0000.
.2.2.
The trouble is, I want to support different colormodes (indexed, rgb), layers, and tilemaps. tilemaps are especially tricky because they’re implemented as a colormode, and the coordinates for them are completely different from the normal pixel coordinates.
I tried to make a temporary Image
object with colormode RGB, draw my pixels into it no matter what the current sprite + layer’s colormode is, but I’m having trouble creating it. I think the issue might be that img:drawImage(app.activeCel.image
(in prepareImage) is failing because the two images’ specs don’t match…? the image returns just fine but when I try to read pixels out of it later they’re very wrong
-- create an image that we can extract colors from
-- note: the image will have colorMode RGB, even if
-- app.activeSprite is TILEMAP or INDEXED
function prepareImage(sprite,layeronly)
local img = Image(sprite.width,sprite.height)
if layeronly then
if not app.activeCel then
app.alert("error: current layer is empty")
return
end
if app.activeCel.image.colorMode==ColorMode.TILEMAP then
img:drawImage(renderTilemapCel(app.activeCel))
else
img:drawImage(app.activeCel.image, app.activeCel.position) -- I believe this is failing b/c the specs don't match
end
else
img:drawSprite(sprite, app.activeFrame)
end
return img
end
-- https://github.com/dacap/export-aseprite-file/blob/master/export.lua#L125-L132
function get_tileset_for_layer(layer)
for i,tileset in ipairs(layer.sprite.tilesets) do
if layer.tileset==tileset then
return tileset
end
end
end
-- is there no better way to convert a tilemap cel into pixels? feels like something the API should do for me, I just haven't been able to figure out how
-- returns: an Image
function renderTilemapCel(cel)
local tilemap = cel.image
assert(tilemap.colorMode==ColorMode.TILEMAP)
assert(cel.sprite.tilesets)
assert(#cel.sprite.tilesets>0,"error: no tilesets found on a tilemap layer")
local tileset = get_tileset_for_layer(cel.layer)
assert(tileset)
local size = tileset.grid.tileSize
local img = Image(tilemap.width*size.width,tilemap.height*size.height)
for it in tilemap:pixels() do
local tileix = app.pixelColor.tileI(it())
local tileimg = tileset:getTile(tileix)
img:drawImage(tileimg,it.x*size.width,it.y*size.height)
end
return img
end
I can imagine a lot of different ways to make this work, but it feels like the API ought to have a function to convert any image or sprite into an RGB image – is there one that I just haven’t found yet? That would save me some time (It would need to also work with sprites that have multiple different layers, e.g. some tilemap layers and some image layers. maybe sprite:flatten() would work for that?)