How to programaically create icon image with transparent background?

I want to do something like this

icon = image(32, 32) — do a bunch of icon:set(...) ...

I want only the dots that I set to be displayed. Everything else is transparent, meaning I can sprite(icon, ...) on any background color and only the dots I set get drawn over the background. How can I do that?

This will create a transparent PNG with a red circle in the center

    fill(255,0,0)
    
    local img = image(100,100)
    setContext(img)
    ellipse(50,50,50)
    setContext()
    
    saveImage("Documents:TestImage", img)

This creates an icon by using a 2D array to set pixel colors.

function setup()
    pix = {width = 9, height = 9,
    {20,20,20,20,20,20,20,20,20},
    {20, 0, 0, 0, 0, 0, 0, 0,20},
    {20, 0, 0, 0,20, 0, 0, 0,20},
    {20, 0, 0, 0,20, 0, 0, 0,20},
    {20, 0,20,20,20,20,20, 0,20},
    {20, 0, 0, 0,20, 0, 0, 0,20},
    {20, 0, 0, 0,20, 0, 0, 0,20},
    {20, 0, 0, 0, 0, 0, 0, 0,20},
    {20,20,20,20,20,20,20,20,20},
    }
    
    icon = image(pix.width, pix.height)
    for y = 1, pix.height do
        for x = 1, pix.width do
            local t = pix[pix.height - y + 1][x]
            icon:set(x,y, 255, 255, 255, t/20 * 255)
        end
    end
end

function draw()
    background(40, 40, 50)
    
    noSmooth()
    sprite(icon, WIDTH/2, HEIGHT/2, HEIGHT/2, HEIGHT/2)
end

Here’s an example just randomly punching holes in a sprite. @Kolosso I wasn’t going to post this since you put an example out sooner, but these are kind of different anyways.

displayMode(FULLSCREEN)

function setup()
    icon=image(200,200)
    setContext(icon)
    fill(0, 255, 181, 255)
    rect(0,0,200,200)
    setContext()
    for z=1,40 do
        holes(math.random(20,180),math.random(20,180),20)
    end
end

function draw()
    background(0, 0, 0, 255)
    sprite("Cargo Bot:Startup Screen",WIDTH/2,HEIGHT/2)
    sprite(icon,WIDTH/2,HEIGHT/2)
end

function holes(x,y,size)
    for x=x,x+size do
        for y=y,y+size do
            icon:set(x,y,0,0,0,0)            
        end
    end   
end

You can also make icons with shaders, but that might be more difficult depending on your abilities.

function setup()
    myIcon = mesh()
    myIcon:addRect(WIDTH/2,HEIGHT/2,100,100)
    myIcon:setColors(255,60,50)
    myIcon.shader = shader(iconShader.vert, iconShader.frag)
end

function draw()
    background(160, 159, 205, 255)
    myIcon:draw()
end

iconShader = {
vert = [[uniform mat4 modelViewProjection; attribute vec4 position; attribute vec4 color; attribute vec2 texCoord; varying lowp vec4 vColor; varying highp vec2 vTexCoord; void main() { vColor = color; vTexCoord = texCoord; gl_Position = modelViewProjection * position; }]],
frag = [[
precision highp float;
varying lowp vec4 vColor;
varying highp vec2 vTexCoord;

float circle(vec2 uv, float radius) {
    return smoothstep(radius, radius - 0.02, length(uv));
}

float band(float t, float x, float w) {
    return smoothstep(x, x + 0.02, t) * smoothstep(x + w, x + w - 0.02, t);
}

float rect(vec2 uv, vec2 pos, vec2 size) {
    return band(uv.x, pos.x, size.x) * band(uv.y, pos.y, size.y);
}

void main()
{
    lowp vec2 uv = vTexCoord - 0.5;

    lowp float outerCircle = circle(uv, 0.5) - circle(uv, 0.42);
    lowp float cross = max(rect(uv, vec2(-0.05,-0.45), vec2(0.1,0.9)), rect(uv, vec2(-0.45,-0.05), vec2(0.9,0.1)));
    gl_FragColor = vColor * max(outerCircle, cross);
}
]]
}

@tsukit It really depends on what you’re trying to make.

Thanks guys!