Create layer and drawing something on it by script

Hello everyone!

I want to make script for splitting RGB Channel to new layers.
I got error message (code attached below)
“lua:25: attempt to index a nil value.”
I think layerR is created but no contents on cel(i.e. nothing in layer) because the layer is newly created is the problem.

rgb

How can I solve it?

I’m not familiar with English, If there are something wrong please forgive me. Thanks!

Code

if app.apiVersion < 1 then
  return app.alert("This script requires Aseprite v1.2.10-beta3")
end

local sprite = app.activeSprite
local frame = app.activeFrame

local currentLayer = app.activeLayer
local img = currentLayer:cel(frame).image

local img_w = sprite.width
local img_h = sprite.height

local layerR = sprite:newLayer()
layerR.name = currentLayer.name .. "_R"

local layerG = sprite:newLayer()
layerG.name = currentLayer.name .. "_G"

local layerB = sprite:newLayer()
layerB.name = currentLayer.name .. "_B"

app.refresh()

local img_R = layerR:cel(frame).image
local img_G = layerG:cel(frame).image
local img_B = layerB:cel(frame).image

for y = 0, img_h - 1, 1 do
  for x = 0, img_w - 1, 1 do
      -- get pixel value
      local color = img:getPixel(x, y)

      local r = Color(color.red, 0, 0, 255)
      local g = Color(0, color.green, 0, 255)
      local b = Color(0, 0, color.blue, 255)

      img_R:drawPixel(x, y, r)
      img_G:drawPixel(x, y, g)
      img_B:drawPixel(x, y, b)
  end
end

app.refresh()

I found alternative method for splitting RGB.
with Ctrl + U (Hue/Saturation,
(i) select HSV+,
(ii) adjust rgba channel which is at right side, if you want to eject g channel, unselect g only.
(iii) set value to -100
).

But I could not found drawing on layer by script! If you have please let me know!

I hope it’s not too intrusive, the script you posted needed a few corrections to fully work, I left comments describing all necessary changes :point_down:

if app.apiVersion < 1 then
    return app.alert("This script requires Aseprite v1.2.10-beta3")
end

local sprite = app.activeSprite
local frame = app.activeFrame

local currentLayer = app.activeLayer
-- You can also save the current cel in a variable - it's going to be useful later to get it's position on the canvas
local currentCel = currentLayer:cel(frame)
local img = currentCel.image

-- You might want to use the size of the image alone, as it can be smaller than the full canvas, saving processing time
local img_w = img.width -- sprite.width
local img_h = img.height -- sprite.height
local colorMode = sprite.colorMode

-- If you want the layers to behave like actual color channels you can use the Addition layer blend mode 

local layerR = sprite:newLayer()
layerR.name = currentLayer.name .. "_R"
-- layerR.blendMode = BlendMode.ADDITION

local layerG = sprite:newLayer()
layerG.name = currentLayer.name .. "_G"
-- layerG.blendMode = BlendMode.ADDITION

local layerB = sprite:newLayer()
layerB.name = currentLayer.name .. "_B"
-- layerB.blendMode = BlendMode.ADDITION

app.refresh()

-- local img_R = layerR:cel(frame).image
-- local img_G = layerG:cel(frame).image
-- local img_B = layerB:cel(frame).image

-- You need to create images first, then assign them to cels

-- A new, empty image is created
local img_R = Image(img_w, img_h, colorMode)
local img_G = Image(img_w, img_h, colorMode)
local img_B = Image(img_w, img_h, colorMode)

for y = 0, img_h - 1, 1 do
    for x = 0, img_w - 1, 1 do
        -- get pixel value
        local colorValue = img:getPixel(x, y)

        -- It's necessary to convert the raw pixel value into a color object
        local color = Color(colorValue)

        -- Use the actual color's alpha value, otherwise the transparency will turn into pure black
        local r = Color(color.red, 0, 0, color.alpha)
        local g = Color(0, color.green, 0, color.alpha)
        local b = Color(0, 0, color.blue, color.alpha)

        img_R:drawPixel(x, y, r)
        img_G:drawPixel(x, y, g)
        img_B:drawPixel(x, y, b)
    end
end

-- Now we can assign the images to cels in their respective layers
sprite:newCel(layerR, frame, img_R, currentCel.position)
sprite:newCel(layerG, frame, img_G, currentCel.position)
sprite:newCel(layerB, frame, img_B, currentCel.position)

app.refresh()
2 Likes

Oh WOW!! I have to create an image first! Thank you for kind tips and advices thkwznk!!!

1 Like