Just Fiddling

Hi All - just posting a little routine I built whilst exploring a way of building up an image like painting. This is a simple project to test an approach. The idea is you sprite an image to the centre of the screen, cover it with a full screen white image (paper) and then use finger/touch pen to gradually reveal the image. The image effect is better in black and white. Thought this may amuse the grand kids as you gradually reveal the image below. Not using masks just making pixels transparent with image:set(). Plenty of scope to improve - library of images, brush size response on touch etc.

Latest Version here


-- Scribble3 by Bri_G

function setup()
    --
    cx,cy = WIDTH/2, HEIGHT/2
    parameter.integer("size",2,6,4)
    parameter.boolean("reveal",false)
    paper = image(WIDTH,HEIGHT)
    parameter.integer("model",1,#piccies,1,
    function() 
        pic = readImage(piccies[model])
        prepare(pic)
    end)
end

function draw()
    -- show the image as it emerges
    background(255, 255, 255, 255)
    spriteMode(CENTER)
    sprite(pic,cx,cy)
    if not reveal then
    sprite(paper,cx,cy)
    end
end

function touched(t)
    -- use the brush
    if t.state == BEGAN or t.state == MOVING then
        setContext(paper)
            tx,ty = math.floor(t.x),math.floor(t.y)
            for x = -size-1,size+1,1 do
                for y = -size-1,size+1,1 do
                    paper:set(tx+x,ty+y,0,0,0,0)
                end
            end
        setContext()
    end
end

function prepare(p)
    --
    bw, bh = spriteSize(p)
    setContext(paper)
        fill(255, 255, 255, 255)
        rectMode(CENTER)
        rect(cx,cy,WIDTH,HEIGHT)
    setContext()
end

piccies = {
            "Documents:pic01",
            "Documents:pic02",
            "Documents:pic03",
            "Documents:pic04"
            }

Let me know if you think of any improvements, will be adding my own and will post.

Image produced from B&W old man image - partially revealed attached.

p.s. the image in the attached picture is not fully developed as the idea is to give an impression of a painted image being built up. Just slowly revealing the complete image would be a little boring. You could use a large image with overlaid grid and small images underneath as a find the treasure game.

@Bri_G Interesting program. That would keep the grandkids busy. I increased the size from -2,2 to -4,4. You could add a slider to adjust the size.

@dave1707 - take your point, first trial with grand daughter - very interested but a little slow so could lose interest. So added the size parameter on the brush and much faster - although I think it loses a little on artistic content as you can quickly end up with a photo. Pursuing other refinements at moment.

Added example at brush size 4.

Hi All - just added the ability to load images (as pic1, pi2 etc) blanking with each new image use your own images. Coloured images will also work but maybe not as dramatic as B&W. Updated code at beginning of post.

nice!

Very nice! Line bw, bh = spriteSize(p) throws an error but works if you delete it

@West - thanks for the feedback, will check out and correct.
@dave1707 - just looking into blendMode() as another way of doing this and found a number of yours, and other members posts relating to this - wow, this forum is great - all you need to do is search!!!

Working on a better version.

@Simeon - on the above point I loaded some old code from Jmv38 which when run bombs straight out of Codea. It is in a gist, in link below if you get time to check it. Probably due to significant changes in Codea (it’s quite old code).

Jmv38 code

@Bri_G @Simeon I tried the JMV38 code and it does crash immediately. I found that if you make the below changes, it works. I don’t know why it crashes, like Bri-G said, probably Codea changes.

In setup() add the 2 lines I show below, colorGrid and back before the buttons comment. Then find them around lines 312 and 246 and comment them out. They run before the setup() function does and that causes Codea to crash. Apparently they used to work in the older version.

Simeon, Can you comment on this. I’m curious what changed. Is this a problem for any code that runs before setup().

PS. It’s the line call in smallColorPattern that’s causing the crash. Apparently you can’t do a line command anymore before setup() runs.

    SRC_background = color(0,0)
    SRC_foreground = color(35, 0, 255, 255)
    
    colorGrid = smallColorPattern()
    back = grid()
    
    -- buttons
    controlPanel()

@dave1707 - thanks, that was a quick find. I tried putting those lines before setup() and they incurred an error. Looks like it is not parsed if added between functions - or maybe it needs to be separated by blank lines if embedded in the code.

@West - replaced my code with a working copy but I can’t find an error. Can you check this update is OK. Thanks.

@Bri_G @West The line bw , bh = spriteSize(p) is an error if you don’t create valid pictures in the piccies table at the end of the code.

@Bri_G @dave1707 Right enough! Works fine now

Hi All, the example above and the following one were inspired by a sketch in Processing by Sen (not sure of his/her full name) called ‘Messy Curve Draw’. The precedent is much better as it used curve lines which I am struggling to construct in Codea(don’t hold your breath).

Here is my second derivative from the idea - sub-titled ‘what can you get from a straight line’ - hope you like it.

p.s. - need to supply your own pics.


-- OneLiner by Bri_G

function setup()
    --
    cp = math.random(5)
    if cp == 0 then cp = 1 end
    if cp > #piccies then cp = #piccies end
    sw,sh = WIDTH,HEIGHT
    cx,ch = WIDTH/2,HEIGHT/2
    paper = image(WIDTH,HEIGHT)
    pic = readImage(piccies[cp])
    setContext(paper)
        fill(255, 255, 255, 255)
        rectMode(CENTER)
        rect(cx,ch,WIDTH,HEIGHT)
    setContext()
    s = 0
    x,y = 0,200
    m = 0
end

function draw()
    -- This sets a dark background color 
    background(40, 40, 50)
    sprite(pic,cx,ch)
    sprite(paper,cx,ch)
    setContext(paper)
        stroke(0,0,0,0)
        strokeWidth(1)
        fill(0, 0, 0, 0)
        blendMode(ONE_MINUS_DST_COLOR,ZERO)
    line(math.random()*sw,math.random()*sh,math.random()*sw,math.random()*sh)
        blendMode(NORMAL)
    setContext()
    s = s+1
    if s >760 then s = 0
    y = math.random(1000)
    end
end

function touched(t)
    --
    if t.state == ENDED then
        cp = math.random(5)
        if cp == 0 then cp = 1 end
        if cp > #piccies then cp = #piccies end
        pic = readImage(piccies[cp])
        setContext(paper)
            fill(255, 255, 255, 255)
            rectMode(CENTER)
            rect(cx,ch,WIDTH,HEIGHT)
        setContext()
    end
end

piccies = {
            "Documents:pic01",
            "Documents:pic02",
            "Documents:pic03",
            "Documents:pic04"
            }


Note - attached image from my pad.

If you would like to see the inspiration follow this link:

Processing Inspiration

@Bri_G Here’s your curved lines.

displayMode(FULLSCREEN)

function setup()
    fill(255)
    strokeWidth(2)
    backingMode(RETAINED)
end

function draw()
    bezier(.01)
    for z=2,#tab do
        line(tab[z-1].x,tab[z-1].y,tab[z].x,tab[z].y)
    end    
end

function bezier(val) 
    x,y={},{}
    for z=1,4 do
        table.insert(x,math.random(WIDTH))
        table.insert(y,math.random(HEIGHT))
    end
    tab={}
    for t=0,1,val do
        px=(1-t)^3*x[1]+3*t*(1-t)^2*x[2]+3*t^2*(1-t)*x[3]+t^3*x[4]
        py=(1-t)^3*y[1]+3*t*(1-t)^2*y[2]+3*t^2*(1-t)*y[3]+t^3*y[4]            
        table.insert(tab,vec2(px,py))
    end
    table.insert(tab,vec2(x[4],y[4]))
end

@dave1707 - thanks for that input, you must have a massive library of routines or a photographic memory of billions of lines of code. Added the routine and posting below for anyone interested.

These curves are great - the precedent uses an earlier form of curve which appears a little more random and can produce blotchy images. When you run the project it just keeps drawing lines so eventually you just reveal the hidden image. I am thinking of putting a limiter on it so that the image is never completed and appears more artistic. In some ways I prefer the first project because you paint where you want to and can stop at any time.

All,

Updated with Bezier code, from @dave1707 above, gives a much better feel to the image buildup.


OneLiner2 by Bri_G
-- thanks to @dave1707 for the Bezier routine - neat

displayMode(FULLSCREEN)
function setup()
    --
    cp = math.random(5)
    if cp == 0 then cp = 1 end
    if cp > #piccies then cp = #piccies end
    sw,sh = WIDTH,HEIGHT
    cx,ch = WIDTH/2,HEIGHT/2
    paper = image(WIDTH,HEIGHT)
    pic = readImage(piccies[cp])
    setContext(paper)
        fill(255, 255, 255, 255)
        rectMode(CENTER)
        rect(cx,ch,WIDTH,HEIGHT)
    setContext()
    s = 0
    x,y = 0,200
    m = 0
end

function draw()
    -- This sets a dark background color 
    background(40, 40, 50)
    bezier(.01)
    sprite(pic,cx,ch)
    sprite(paper,cx,ch)
    setContext(paper)
        stroke(0,0,0,0)
        strokeWidth(1)
        fill(0, 0, 0, 0)
        blendMode(ONE_MINUS_DST_COLOR,ZERO)
        for z=2,#tab do
            line(tab[z-1].x,tab[z-1].y,tab[z].x,tab[z].y)
        end    
        blendMode(NORMAL)
    setContext()
    s = s+1
    if s >760 then s = 0
    y = math.random(1000)
    end
end

function touched(t)
    --
    if t.state == ENDED then
        cp = math.random(5)
        if cp == 0 then cp = 1 end
        if cp > #piccies then cp = #piccies end
        pic = readImage(piccies[cp])
        setContext(paper)
            fill(255, 255, 255, 255)
            rectMode(CENTER)
            rect(cx,ch,WIDTH,HEIGHT)
        setContext()
    end
end

function bezier(val) 
    x,y={},{}
    for z=1,4 do
        table.insert(x,math.random(WIDTH))
        table.insert(y,math.random(HEIGHT))
    end
    tab={}
    for t=0,1,val do
        px=(1-t)^3*x[1]+3*t*(1-t)^2*x[2]+3*t^2*(1-t)*x[3]+t^3*x[4]
        py=(1-t)^3*y[1]+3*t*(1-t)^2*y[2]+3*t^2*(1-t)*y[3]+t^3*y[4]            
        table.insert(tab,vec2(px,py))
    end
    table.insert(tab,vec2(x[4],y[4]))
end

piccies = {
            "Documents:pic01",
            "Documents:pic02",
            "Documents:pic03",
            "Documents:pic04"
            }

@Bri_G I have about 600 projects, so if anyone has a question, I usually have a project I can strip down for an example. I usually write more projects when I think of something different to try.