There you go!
Note this is just my crappy test and it needs integration into your own workflow.
It is using the PNG extension here:
I could not find a decent png decoder (read working) in pure lua to create an editor extension and I’m not happy with a solution that needs an external app.
-- Convex hull
-- https://www.rosettacode.org/wiki/Convex_hull#Lua
-- MIT license (?)
local function ccw(a,b,c)
return (b.x - a.x) * (c.y - a.y) > (b.y - a.y) * (c.x - a.x)
end
local function pop_back(ta)
table.remove(ta,#ta)
return ta
end
local function convexHull(pl)
if #pl == 0 then
return {}
end
table.sort(pl, function(left,right)
return left.x < right.x
end)
local h = {}
-- lower hull
for i,pt in pairs(pl) do
while #h >= 2 and not ccw(h[#h-1], h[#h], pt) do
table.remove(h,#h)
end
table.insert(h,pt)
end
-- upper hull
local t = #h + 1
for i=#pl, 1, -1 do
local pt = pl[i]
while #h >= t and not ccw(h[#h-1], h[#h], pt) do
table.remove(h,#h)
end
table.insert(h,pt)
end
table.remove(h,#h)
return h
end
local function get_pixel_rgba(pixels, width, x, y)
local index = y * width * 4 + x * 4 + 1
local r = pixels[index + 0]
local g = pixels[index + 1]
local b = pixels[index + 2]
local a = pixels[index + 3]
return r,g,b,a
end
function init(self)
local rel_path = "<your image here>"
local abs_path = "<absolute path where to save>"
local file = io.open(abs_path, "rb")
local file = file:read("*a")
local buf, w, h = png.decode_rgba(file, true)
local pixels = buffer.get_stream(buf, hash("pixels"))
local points = {}
for x = 0, w - 1 do
for y = 0, h - 1 do
local r, g, b, a = get_pixel_rgba(pixels, w, x, y)
if a > 128 then
table.insert(points, {x=x, y=y})
end
end
end
local ch = convexHull(points)
local data = "shape_type: TYPE_HULL\n"
for i = 1, #ch do
data = data .. "data: " .. ch[i].x .. " data: " .. ch[i].y .. " data: 0\n"
end
-- write the resulting convex hull
local save_path = "<save path>"
local save_file = io.open(save_path, "w")
save_file:write(data)
save_file:close()
end