Open4
Asepriteをプログラムで操作する方法
原理
Asperiteはピクセルアートを描くためのグラフィックスソフトですが、裏側でプログラムを動作させることが可能で、それによって通常Asepriteの有していない機能を利用することが可能になります。
記述言語はLua。
準備
- まずは、適当なLuaプログラムをテキストエディタで編集します。(保存は.lua形式)
- 次にそのプログラムをAseprite/scriptsフォルダ配下(OSによって異なる?)に置きます
- Windows11では、C:¥User¥ユーザー名¥AppData¥Roaming¥Aseprite¥scriptsでした
- Aseprite上部メニュー>File>Scripts>Open Scripts Folderをクリックすれば.luaファイルを置くべき場所がわかります
- Asepriteを起動
- Aseprite上部メニュー>File>Scriptsの内部にファイル名が記載されていれば成功
- それをクリックすれば当該ファイルのluaで記述したプログラムが動作します
- Aseprite上部メニュー>File>Scriptsの内部にファイル名が記載されていなければ、Aseprite上部メニュー>File>Scripts>RescanScripts Folder(ないしはF5キーを押下)をクリックしましょう
サンプル
以下は編集最中の画像を32x32サイズに分割し、それぞれ別名のpng形式で保存するプログラム
luaとかAsperiteのAPIよくわからん・・・
SpriteSplit.lua
local sprite = app.activeSprite
local width = 32 -- 分割する幅
local height = 32 -- 分割する高さ
for y = 0, sprite.height - 1, height do
for x = 0, sprite.width - 1, width do
local filename = string.format("SplitsResult/tile_%d_%d.png", y / height, x / width)
sprite:saveCopyAs(filename)
end
end
for y = 0, sprite.height - 1, height do
for x = 0, sprite.width - 1, width do
local filename = string.format("SplitsResult/tile_%d_%d.png", y / height, x / width)
local newSprite = app.open(filename)
local rect = Rectangle(x, y, math.min(width, sprite.width - x), math.min(height, sprite.height - y))
newSprite:crop(rect)
newSprite:saveAs(filename)
newSprite:close()
end
end
なお、ファイルの読み書きの基準はAseprite.exeの存在するフォルダ
編集最中の画像を対象に、Mainレイヤーに存在する現在のフォアグラウンドカラー(ペン色)と同じ色のピクセルを全て選択した後、選択したピクセルは白に、それ以外を黒に塗りつぶしたMaskレイヤーを作成する処理。(フレームが存在する場合は全フレームにその処理を繰り返す)
CreateMask.lua
local sprite = app.sprite -- アクティブなスプライトを取得
function main()
if not sprite then
app.alert("アクティブな画像ファイルが存在しません。")
return
end
-- Mainレイヤーを探す
local mainLayer = nil
for _, layer in ipairs(sprite.layers) do
if layer.name == "Main" then
mainLayer = layer
break
end
end
if not mainLayer then
app.alert("Mainレイヤーが見つかりません。")
return
end
-- Maskレイヤーを取得または作成
local maskLayer = nil
for _, layer in ipairs(sprite.layers) do
if layer.name == "Mask" then
maskLayer = layer
break
end
end
if not maskLayer then
maskLayer = sprite:newLayer()
maskLayer.name = "Mask"
end
-- 記録色を取得
local recordColor = app.fgColor
local black = app.pixelColor.rgba(0, 0, 0, 255)
local white = app.pixelColor.rgba(255, 255, 255, 255)
for _, frame in ipairs(sprite.frames) do
local mainCel = mainLayer:cel(frame)
if not mainCel then goto continue end
local mainImage = mainCel.image
local offset = mainCel.position
-- Mask画像を黒で塗りつぶし作成
local maskImage = Image(sprite.width, sprite.height, ColorMode.RGBA)
maskImage:clear(black)
-- 指定色と一致するピクセルを白で描画(位置補正あり)
for it in mainImage:pixels() do
local pixelValue = mainImage:getPixel(it.x, it.y)
local r = app.pixelColor.rgbaR(pixelValue)
local g = app.pixelColor.rgbaG(pixelValue)
local b = app.pixelColor.rgbaB(pixelValue)
local a = app.pixelColor.rgbaA(pixelValue)
if r == recordColor.red and g == recordColor.green and b == recordColor.blue and a == recordColor.alpha then
local ex = it.x + offset.x
local ey = it.y + offset.y
if ex >= 0 and ey >= 0 and ex < maskImage.width and ey < maskImage.height then
maskImage:putPixel(ex, ey, white)
end
end
end
-- MaskレイヤーのCelを作成または上書き
local maskCel = maskLayer:cel(frame)
if not maskCel then
maskCel = sprite:newCel(maskLayer, frame, maskImage, Point(0, 0))
else
maskCel.image = maskImage
maskCel.position = Point(0, 0)
end
maskCel.opacity = 255
::continue::
end
app.alert("処理が完了しました。")
end
main()
背景を単色(緑)で塗りつぶしたChromakeyレイヤーを作成する(フレームが存在する場合は全フレームにその処理を繰り返す)
CreateChromakey.lua
local sprite = app.sprite
if not sprite then
app.alert("アクティブなスプライトがありません。")
return
end
-- すでに存在している Chromakey レイヤーがあるか確認
local chromaLayer = nil
for _, layer in ipairs(sprite.layers) do
if layer.name == "Chromakey" then
chromaLayer = layer
break
end
end
-- なければ新規作成
if not chromaLayer then
chromaLayer = sprite:newLayer()
chromaLayer.name = "Chromakey"
end
-- 緑色 (r=0, g=255, b=0, a=255)
local green = app.pixelColor.rgba(0, 255, 0, 255)
for _, frame in ipairs(sprite.frames) do
-- 全体を緑で塗ったイメージ作成
local image = Image(sprite.width, sprite.height, ColorMode.RGBA)
image:clear(green)
-- 既存の Cel があれば更新、なければ新規作成
local cel = chromaLayer:cel(frame)
if cel then
cel.image = image
cel.position = Point(0, 0)
else
sprite:newCel(chromaLayer, frame, image, Point(0, 0))
end
end
app.alert("Chromakeyレイヤーが作成され、背景が緑で塗られました。")