Unable to draw to transparent image to dlg:canvas

I’m trying to use GraphicsContext:drawImage() to draw an image to a Dialog:canvas()
but no matter what I do the background ends up black.

image

SNAKlogo

local img_logo = Image{ fromFile=(app.fs.normalizePath(app.fs.userConfigPath…“\scripts\SNAK\SNAKlogo.png”)) }
DLG = Dialog(“gc:drawImage test”)
DLG:canvas{
width = 112,
height = 48,
onpaint=function(ev)
local gc = ev.context
gc:drawImage(img_logo, 0, 0)
end
}
DLG:show()

Also as aside has there been any progress on this issue? New UIImage kind of object to cache offscreen images/textures · Issue #89 · aseprite/api · GitHub
Loading an image introduces a small delay when loading my script so this would be very useful.

2 Likes

Hi @MM102,

For for the first issue you mentioned, what about either recreating the background checker grid or using the theme window face color?

local sprite = app.activeSprite
if not sprite then return end

local frame = app.activeFrame
if not frame then return end

local spriteWidth = sprite.width
local spriteHeight = sprite.height

local docPref = app.preferences.document(sprite)
local bgPref = docPref.bg
local bgGridSize = bgPref.size
local wGrid = bgGridSize.width
local hGrid = bgGridSize.height
if wGrid < 2 then wGrid = 2 end
if hGrid < 2 then hGrid = 2 end

local aCheckerAse = bgPref.color1
local bCheckerAse = bgPref.color2
local aCheckHex = aCheckerAse.rgbaPixel
local bCheckHex = bCheckerAse.rgbaPixel
aCheckHex = 0xff000000 | aCheckHex
bCheckHex = 0xff000000 | bCheckHex

local dlg = Dialog { title = "Preview" }
dlg:canvas {
    width = 128,
    height = 128,
    onpaint = function(event)
        local img = Image(spriteWidth, spriteHeight)

        -- Alternatively, try img:clear with
        -- app.theme.color.window_face.rgbaPixel
        local pxItr = img:pixels()
        for pixel in pxItr do
            local hex = bCheckHex
            local x = pixel.x
            local y = pixel.y
            if (((x // wGrid) + (y // hGrid)) % 2) ~= 1 then
                hex = aCheckHex
            end
            pixel(hex)
        end

        local flatSprite = Image(spriteWidth, spriteHeight)
        flatSprite:drawSprite(sprite, frame)

        img:drawImage(
            flatSprite,
            Point(0, 0),
            255,
            BlendMode.NORMAL)

        local gc = event.context
        gc:drawImage(img, 0, 0)
    end
}

dlg:show { wait = false }

I’ve dabbled in a custom preview, and realize that there are a lot of tradeoffs between performance v. updating after user inputs, so caveat emptor, the script is sloppy. Some variables you may want to cache up top, others may need to be updated with every canvas repaint. Nevertheless, hopefully it gives you an idea of what I mean.

Jeremy

1 Like

Hi @MM102, definitely a bug in the GraphicsContext:drawImage() function, but the version with srcRect and dstRect should work if the image (png) is in RGB mode:

onpaint=function(ev)
  local gc = ev.context
  local rc = img_logo.bounds
  gc.blendMode = BlendMode.SRC_OVER
  gc:drawImage(img_logo, rc, Rectangle(0, 0, rc.w, rc.h))
end

No progress about this one yet.

2 Likes