2020/01/03(金) [n年前の日記]
#1 [love2d] love2dでCanvasをpng画像として保存する
love2d は Canvas 上にアレコレ描画して画面に表示するけれど。その、Canvas を、画像保存することはできるのかどうかが気になってきたので実験してみたり。もし、画像保存ができるなら、グラフィック関係のツールを love2d を使って作ることだってできてしまうのかもしれない。
ググってみたら、以下のやり取りが参考になった。
_saving a canvas as an image - Page 2 - LOVE
Canvas には newImageData() というメソッドがあるので、それを使うと ImageData を得られるらしい。ImageData が得られれば、encode("png") でpng画像のフォーマットに変換できる模様。
_Canvas:newImageData (日本語) - LOVE
_ImageData:encode (日本語) - LOVE
本来は、 _love.filesystem.write で保存できそうなものだけど、任意のフォルダに保存したい場合は Lua の io.open()、io.close() を使ったほうがいい、みたいな話が前述の掲示板上でのやり取りで述べられているのかな。たぶん。
ググってみたら、以下のやり取りが参考になった。
_saving a canvas as an image - Page 2 - LOVE
Canvas には newImageData() というメソッドがあるので、それを使うと ImageData を得られるらしい。ImageData が得られれば、encode("png") でpng画像のフォーマットに変換できる模様。
_Canvas:newImageData (日本語) - LOVE
_ImageData:encode (日本語) - LOVE
本来は、 _love.filesystem.write で保存できそうなものだけど、任意のフォルダに保存したい場合は Lua の io.open()、io.close() を使ったほうがいい、みたいな話が前述の掲示板上でのやり取りで述べられているのかな。たぶん。
◎ ソース。 :
手元で動作確認。環境は、Windows10 x64 1909 + love2d 11.3。
_conf.lua
_main.lua
conf.lua と main.lua を任意のフォルダに入れて、「love フォルダ名」で実行できる。
実行すると、以下のようなウインドウが開く。

スペースキーを叩くと、フォルダと同階層に xxxx-xx-xx_xx-xx-xx.png の形で保存される。結果画像は以下。

_2020-01-03_20-11-11.png
ということで、love2d の Canvas を png画像として保存することは可能らしい。
_conf.lua
function love.conf(t) t.version = "11.3" -- love2d version t.window.title = "Export canvas - love2d" t.window.vsync = 1 t.window.width = 320 t.window.height = 240 -- t.window.fullscreen = true -- t.window.fullscreentype = "exclusive" end
_main.lua
-- Export canvas on love2d
function love.load()
love.graphics.setDefaultFilter("nearest", "nearest")
canvas = love.graphics.newCanvas(320, 240)
font = love.graphics.newFont(16)
req_export = false
now_time_str = ""
end
function love.update(dt)
now_time_str = os.date("%Y-%m-%d_%H-%M-%S")
end
function love.draw()
-- set canvas
love.graphics.setCanvas(canvas)
-- clear canvas
love.graphics.clear(0, 0, 0, 0)
-- draw text
love.graphics.setFont(font)
love.graphics.setColor(0, 1, 0, 1)
love.graphics.print("FPS: " .. tostring(love.timer.getFPS()), 2, 2)
love.graphics.setColor(0, 1, 1, 1)
love.graphics.print("SPACE key : Export canvas as png", 2, 20)
love.graphics.setColor(1, 1, 0, 1)
love.graphics.print(now_time_str, 2, 40)
-- unset canvas
love.graphics.setCanvas()
-- draw canvas to screen
love.graphics.setColor(1, 1, 1, 1)
love.graphics.draw(canvas)
if req_export then
req_export = false
-- export canvas as png
local imagedata = canvas:newImageData()
local filedata = imagedata:encode("png")
local filename = now_time_str .. ".png"
-- write file
local filepng = io.open(filename, "wb")
if filepng ~= nil then
filepng:write(filedata:getString())
filepng:close()
end
local ty = love.graphics.getHeight() - 40
love.graphics.print("Export !", 2, ty)
end
end
function love.keypressed(key, isrepeat)
if key == "escape" then
-- ESC key to exit
love.event.quit()
elseif key == "space" then
-- SPACE key to export canvas
req_export = true
end
end
conf.lua と main.lua を任意のフォルダに入れて、「love フォルダ名」で実行できる。
実行すると、以下のようなウインドウが開く。

スペースキーを叩くと、フォルダと同階層に xxxx-xx-xx_xx-xx-xx.png の形で保存される。結果画像は以下。

- Canvas のアルファチャンネルを 0.0 で塗ってから文字列を描画しているので、アルファチャンネルを持った png画像が得られている。
- 文字列を描画する際にアンチエイリアスがかかっているせいか、ちょっと輪郭が汚くなっている。
ということで、love2d の Canvas を png画像として保存することは可能らしい。
◎ love2dで現在時刻を取得する。 :
スクリプト内で使っているので、ついでにメモ。
Lua の場合、os.date() で現在時刻を取得できる。
os.date("xxxx") とフォーマット文字列を指定することで、任意のフォーマットで文字列が取得できる。フォーマットについては、C言語の strftime に従うとのこと。
_os/date - Lua Memo
_Man page of STRFTIME
Lua の場合、os.date() で現在時刻を取得できる。
os.date("xxxx") とフォーマット文字列を指定することで、任意のフォーマットで文字列が取得できる。フォーマットについては、C言語の strftime に従うとのこと。
_os/date - Lua Memo
_Man page of STRFTIME
[ ツッコむ ]
以上、1 日分です。