Skip to content

Instantly share code, notes, and snippets.

@Trylobot
Last active February 10, 2022 01:26
Show Gist options
  • Save Trylobot/54c3d5d40a2cbe0c0293a67a14bf7b82 to your computer and use it in GitHub Desktop.
Save Trylobot/54c3d5d40a2cbe0c0293a67a14bf7b82 to your computer and use it in GitHub Desktop.
EXTernal PALette transFORM .LUA - Aseprite script prototype, version 1
-- EXTernal PALette transFORM .LUA - Aseprite script prototype, version 1
-- load sg2-format palette image
-- load sg2 sprite
-- validate
-- move between palette states by applying palette transformations
local dlg = Dialog { title = "External Palette Transformation " }
local pal_img = nil
local pal_height_px = 0
local expected_palette_img_width = 256 -- TODO: this is hardcoded for now
local mode = "to_color" -- { "to_color", "to_greyscale" }
local palette_reverse_lookup = nil
-- TODO: support other sg2-format palette structures
-- dlg:radio {
-- id = "palette_structure_radio",
-- label = "Palette Structure",
-- text = "row-major 256-column left-to-right greyscale",
-- selected = true,
-- -- onclick =
-- }
dlg:file {
id = "palette_filename_input",
label = "Palette File",
title = "Open...",
open = true,
save = false,
filename = "",
filetypes = { "png" },
onchange = function()
-- load palette image
pal_img = Image{ fromFile = dlg.data.palette_filename_input }
pal_height_px = pal_img.height
-- create lookup tables for each row
palette_reverse_lookup = {}
for y = 0, (pal_height_px - 1) do
local pal_table = {}
for pal_px in pal_img:pixels( Rectangle{ 0,y, expected_palette_img_width,1 }) do
local pal_pixel_value = pal_px()
pal_table[ pal_pixel_value ] = Color{ r = pal_px.x, g = pal_px.x, b = pal_px.x, a = 255 }
end
palette_reverse_lookup[ y ] = pal_table -- save
end
-- update gui
dlg:modify {
id = "palette_row_slider",
max = (pal_height_px - 1),
value = 1, -- also sort of shows user how many palette rows there are
enabled = true,
}
dlg:modify {
id = "go_button",
enabled = true, -- ?
}
end,
}
dlg:slider {
id = "palette_row_slider",
label = "Palette Row",
min = 0,
max = pal_height_px,
value = 0,
visible = true,
enabled = false,
}
dlg:radio {
id = "transformation_mode_radio_to_color",
label = "Mode",
text = "Color",
selected = true,
onclick = function()
mode = "to_color"
dlg:modify {
id = "transformation_mode_radio_to_color",
selected = true
}
dlg:modify {
id = "transformation_mode_radio_to_greyscale",
selected = false
}
end,
}
dlg:radio {
id = "transformation_mode_radio_to_greyscale",
-- label = "Mode",
text = "Greyscale",
selected = false,
onclick = function()
mode = "to_greyscale"
dlg:modify {
id = "transformation_mode_radio_to_color",
selected = false
}
dlg:modify {
id = "transformation_mode_radio_to_greyscale",
selected = true
}
end,
-- enabled = false -- TODO: enable this when it is working properly
}
dlg:separator{}
function transform( px_color, mode, pal_img, selected_palette_row )
if mode == "to_color" then
-- TODO: validate px_color is a grey color (R==G==B)
if px_color.red == px_color.blue and px_color.blue == px_color.green then
-- is grey
-- return the color of the pixel at palette_image location ( greyscale_value, palette_row )
return Color( pal_img:getPixel( px_color.red, selected_palette_row ))
else
return px_color -- transformation unsuccessful; given color is not grey
end
elseif mode == "to_greyscale" then
-- check lookup table
local lookup_color = palette_reverse_lookup[ selected_palette_row ][ px_color.rgbaPixel ]
if lookup_color then
return lookup_color
else
return px_color -- transformation unsuccessful; given color not present in palette
end
end
end
dlg:button {
id = "go_button",
--label = ""
text = "Apply",
enabled = false,
onclick = function()
-- change to RGB (required for script to work, for now)
app.command.ChangePixelFormat{ format="rgb" }
local img = app.activeCel.image
if not img then
return print('No active image')
end
local img_new = Image( img ) -- clone active image
-- execute transformation
for px in img_new:pixels() do
local px_color = Color( px() )
local new_color = transform( px_color, mode, pal_img, dlg.data.palette_row_slider )
px( app.pixelColor.rgba( new_color.red, new_color.green, new_color.blue, px_color.alpha ))
end
-- apply changes all at once
img:drawImage( img_new )
app.refresh()
end,
}
dlg:show { wait = false }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment