Hi @pancelor,
Welcome aboard.
Here’s how I go about converting a tilemap image to a another color mode image. The function assigns the color mode of the sprite, not the source image, to the target image. As a precaution, I transfer the transparentColor
and colorSpace
to the target. I just grab the index from the pixel iterator; I’ve never had to use app.pixelColor.tileI
, so I can’t say much about it.
---Converts an image from a tile set layer to a regular
---image. Supported in Aseprite version 1.3 or newer.
---@param imgSrc Image source image
---@param tileSet userdata tile set
---@param sprClrMode ColorMode sprite color mode
---@return Image
function AseUtilities.tilesToImage(imgSrc, tileSet, sprClrMode)
local tileDim = tileSet.grid.tileSize
local tileWidth = tileDim.width
local tileHeight = tileDim.height
-- The source image's color mode is 4 if it is a tile map.
-- Assigning 4 to the target image when the sprite color
-- mode is 2 (indexed) crashes Aseprite.
local specSrc = imgSrc.spec
local specTrg = ImageSpec {
width = specSrc.width * tileWidth,
height = specSrc.height * tileHeight,
colorMode = sprClrMode,
transparentColor = specSrc.transparentColor
}
specTrg.colorSpace = specSrc.colorSpace
local imgTrg = Image(specTrg)
local pxItr = imgSrc:pixels()
for pixel in pxItr do
imgTrg:drawImage(
tileSet:getTile(pixel()),
Point(pixel.x * tileWidth,
pixel.y * tileHeight))
end
return imgTrg
end
Here is a thread about converting an indexed color mode image to RGB color mode:
With grayscale to RGB, each 16 bit hexadecimal value in an image would be converted to 32 bit; for example, 0xaabb
would become 0xaabbbbbb
.
For scripting projects of even moderate size, it’s tough to give decent advice. Details, such as whether you need to account for linked cels or for the relationship between group layers and their children, can totally reshape how a script is organized. So take what I say, esp. the advice below, with a grain of salt.
There’s a command to change a sprite’s color mode. I wrap this in a helper function to make it easier to use with the API’s enum constants.
---Wrapper for app.command.ChangePixelFormat which
---accepts an integer constant as an input. The constant
---should be included in the ColorMode enum: INDEXED,
---GRAY or RGB. Does nothing if the constant is invalid.
---@param format ColorMode|integer format constant
function AseUtilities.changePixelFormat(format)
if format == ColorMode.INDEXED then
app.command.ChangePixelFormat { format = "indexed" }
elseif format == ColorMode.GRAY then
app.command.ChangePixelFormat { format = "gray" }
elseif format == ColorMode.RGB then
app.command.ChangePixelFormat { format = "rgb" }
end
end
If you find this useful, cache the old sprite color mode, convert to RGB, convert to the old color mode upon the script’s conclusion.
Conversion shouldn’t alter the sprite too much when going from less information (gray, indexed) to more (RGB) and back again. However, if you’re concerned about that, you could try duplicating the sprite via the copy constructor, then close the duplicate when the script is finished. Duplicating a sprite would also let you flatten it.
Cheers,
Jeremy