2020/01/07(火) [n年前の日記]
#1 [love2d] love2dのImageDataについて動作確認
love2d には ImageData なるクラス(?)があるようで。画像の生データを入れて管理できるらしいけど、どういうことができそうなのかちょっとよく分からなかったので、動作確認してみたり。環境は、Windows10 x64 1909 + love2d 11.3。
こんな感じでどうか。
ImageData を使って、グラデーションを作成。カーソルキーの上下で明るさを変える処理も入れてみた。 *1
つまり、ImageData を使えば、1ドットずつ RGBA を指定して画像を作成、みたいなことができるのかな。たぶん。
RGBAの各値として渡せるのは、0.0 - 1.0 の値で、0 - 255 ではない点に注意。love2d 11.0 より前は 0 - 255 を渡していたけれど、love2d 11.0 以降は 0.0 - 1.0 の範囲になった模様。
何にせよ、こういうクラスがあるのであれば、フィルタ処理等も書けるのかもしれないな…。もっとも、フィルタ処理などは、 _Shader を使ったほうが良さそうかな…。事前に何かしら画像処理をして、そのデータを持っておいて時々使う、といった用途であれば、ImageData は便利なのかもしれない。たぶん。
こんな感じでどうか。
ImageData を使って、グラデーションを作成。カーソルキーの上下で明るさを変える処理も入れてみた。 *1
つまり、ImageData を使えば、1ドットずつ RGBA を指定して画像を作成、みたいなことができるのかな。たぶん。
◎ ソース。 :
_conf.lua
_main.lua
function love.conf(t) t.version = "11.3" -- love2d version t.window.title = "ImageData test - love2d" t.window.vsync = 1 t.window.width = 640 t.window.height = 480 -- t.window.fullscreen = true -- t.window.fullscreentype = "exclusive" end
_main.lua
-- ImageData test on love2d function make_gradation(imgdata) local w, h = imgdata:getDimensions() local x, y for y = 0, (h - 1) do for x = 0, (w - 1) do local r, g, b, a r = x / (w - 1) g = y / (h - 1) b = (x / ((w - 1) / 4)) % 1.0 a = (y / ((h - 1) / 4)) % 1.0 imgdata:setPixel(x, y, r, g, b, a) end end end function brighten(x, y, r, g, b, a) r = math.min(r * 1.5, 1.0) g = math.min(g * 1.5, 1.0) b = math.min(b * 1.5, 1.0) return r, g, b, a end function darken(x, y, r, g, b, a) r = math.max(r * 0.75, 0.0) g = math.max(g * 0.75, 0.0) b = math.max(b * 0.75, 0.0) return r, g, b, a end function love.load() love.graphics.setDefaultFilter("nearest", "nearest") local w, h = love.graphics.getDimensions() imgdata = love.image.newImageData(w, h) make_gradation(imgdata) img = love.graphics.newImage(imgdata) end function love.update(dt) end function love.draw() love.graphics.clear(0, 0, 0, 1) love.graphics.setColor(1, 1, 1, 1) love.graphics.draw(img, 0, 0) love.graphics.print("Hit Up/Down key", 2, 20) love.graphics.print("FPS: " .. tostring(love.timer.getFPS()), 2, 2) end function love.keypressed(key, isrepeat) if key == "escape" then -- ESC key to exit love.event.quit() elseif key == "up" then imgdata:mapPixel(brighten) img:replacePixels(imgdata) elseif key == "down" then imgdata:mapPixel(darken) img:replacePixels(imgdata) end end
◎ 少し解説。 :
- imgdata = love.image.newImageData(w, h) で ImageData を作成できる。
- imgdata:setPixel(x, y, r, g, b, a) で、(x, y) の位置のドットにRGBAを指定できる。
- love.graphics.newImage(imgdata) で、ImageData から Image を作れる。Image にすれば、Canvas に描画することができる。
- imgdata:mapPixel(関数) で、ImageData の全ドットに対して処理ができる。
- Image:replacePixels(imgdata) で、Image の内容を ImageData で置き換えることができる。
RGBAの各値として渡せるのは、0.0 - 1.0 の値で、0 - 255 ではない点に注意。love2d 11.0 より前は 0 - 255 を渡していたけれど、love2d 11.0 以降は 0.0 - 1.0 の範囲になった模様。
何にせよ、こういうクラスがあるのであれば、フィルタ処理等も書けるのかもしれないな…。もっとも、フィルタ処理などは、 _Shader を使ったほうが良さそうかな…。事前に何かしら画像処理をして、そのデータを持っておいて時々使う、といった用途であれば、ImageData は便利なのかもしれない。たぶん。
◎ 参考ページ。 :
_ImageData (日本語) - LOVE
_ImageData:setPixel (日本語) - LOVE
_ImageData:mapPixel (日本語) - LOVE
_(Image):replacePixels (日本語) - LOVE
_ImageData:setPixel (日本語) - LOVE
_ImageData:mapPixel (日本語) - LOVE
_(Image):replacePixels (日本語) - LOVE
*1: ただし、今回は、一度明るさを変更すると元のRGB値が微妙に失われていくので、最初の状態には戻らない。
[ ツッコむ ]
以上です。