Not really sure how useful this is but I thought I’d share it anyway. Defold PNG is a Defold native extension that allows you to inspect, load and save PNG files. Usage:
-- load my.png from disk
local f = io.open("my.png", "rb")
local bytes = f:read("*a")
-- read the PNG header
local info = png.info(bytes)
print(info.width)
print(info.height)
print(info.colortype) -- png.RGB, png.RGBA, png.GREY, png.GREY_ALPHA or png.PALETTE
print(info.bitdepth)
-- decode the PNG to a Defold buffer in RGB(A) format
local buf, w, h = png.decode_rgb(bytes)
local buf, w, h = png.decode_rgba(bytes)
-- use buffer as a sprite texture
local resource_path = go.get("#sprite", "texture0")
local header = { width = w, height = h, type = resource.TEXTURE_TYPE_2D, format = resource.TEXTURE_FORMAT_RGBA, num_mip_maps = 1 }
resource.set_texture(resource_path, header, buf)
-- create 100x100 raw pixels of random colors
local w, h = 100, 100
local pixels = ""
for i=1,w*h do
pixels = pixels .. string.char(math.random(1,255), math.random(1,255), math.random(1,255), 255)
end
--- encode raw RGB(A) pixels into a PNG
local bytes = png.encode_rgb(pixels, w, h)
local bytes = png.encode_rgba(pixels, w, h)
-- write bytes to foo.png
local f = io.open("foo.png", "wb")
f:write(bytes)
f:flush()
f:close()
Very useful, thanks! How difficult would it be to do something similar for GIFs? Because my game is 100% deterministic a super-stretch goal of mine is to record player input and when they solve a puzzle play back the key inputs to create a GIF of their solution that they can then tweet/whatever. Would be happy to look into extensions and do it myself if/when the time comes, just wondering if it’s even feasible.
You would probably want to save the game state and only make the GIF after with a custom render script. Use a render target to render everything to a texture, downscale each frame, then batch process them to produce the GIF. There are still mystery steps which I am not clear on doing still but with buffers and native extensions I think it should all be possible right now. Could also save every x frame textures downscaled to memory too and then produce the GIF at game over based on last few frames with a few seconds/msecs inbetween or based on when moves are made.
Well this is pretty awesome, thanks a lot for making it! Just a little bit faster than decoding PNGs with pure Lua, haha. As a test I loaded a 17MB PNG (about 5000x3000px) and it decoded in just a tad over 1 second. This definitely opens up some possibilities.
One question though: is there some way to get a loaded PNG onto a GUI node? gui.new_texture and all the related functions require a string for the texture buffer . . .
Now, I could ofc add support for returning decoded image as a string instead of a buffer, but I reasoned that since image.load() exists there was no need for it.