Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Help with draw() function

edited April 20 in Questions Posts: 3
Okay so when I have a couple of projects where when I try to draw to the screen after calling a sub function from the draw function and then returning to the draw function nothing happens. Why is this? Is it a bug? Please help me.

Here is code:

function setup()
parameter.integer("mod",0,150,75)
centx = WIDTH/2
centy = HEIGHT/2
fail = false
end

function enhance()
img = image(CAMERA)
if img == nil then
fail = true
else
width = img.width
height = img.height
for y = 1, height do
for x = 1, width do
r,g,b = img:get(x,y)
img:set(x,y,r,math.min(g+mod,255),b)
end
end
fail = false
end
end

function draw()
background(40, 40, 50)
enhance()
if fail == false then
sprite(img,centx,centy,WIDTH,HEIGHT)
end
end

Comments

  • dave1707dave1707 Mod
    Posts: 9,441

    @possibleAdam You can call sub functions from draw. That’s done all the time. I’m just not sure what you’re trying to do. Are you trying to have the camera constantly taking a picture that you’re changing the green intensity. I’m off to bed, so if someone doesn’t help you I’ll do it tomorrow.

  • edited April 15 Posts: 2,364
    @possibleAdam - I suggest you take the enhance function out of draw() and add a touch() function which calls enhance whenever you touch the screen the image will be taken and enhanced. Alternatively you could consider a parameter.action() call to do the same but you need to take enhance() out of the draw() function. Try it yourself, I'll post code later when I get time.

    Edit: please enclose your code within two sets of tilde brackets so it formats correctly (ie ~~~)
  • dave1707dave1707 Mod
    edited April 15 Posts: 9,441

    @possibleAdam I'm awake. Your problem is the dual for loops with img:get and set in enhance are slowing Codea to a crawl. I commented them out plus I added collectgarbage in enhance otherwise Codea will crash because of the constant update from image(CAMERA). So the call to enhance isn’t the problem.

    PS. I’ll comment more later.

    PSS. There might be a bug with img:get.

    function setup()
        parameter.integer("mod",0,150,75)
        parameter.watch("fps")
        centx = WIDTH/2
        centy = HEIGHT/2
        fail = false
    end
    
    function enhance()
        img = image(CAMERA)
        collectgarbage()
        if img == nil then
            fail = true
        else
            width = img.width
            height = img.height
            for y = 1, height do
                for x = 1, width do
                    --r,g,b = img:get(x,y)
                    --img:set(x,y,r,math.min(g+mod,255),b)
                end
            end
            fail = false
        end
    end
    
    function draw()
        background(40, 40, 50)
        enhance()
        if fail == false then
            sprite(img,centx,centy,WIDTH,HEIGHT)
        end
        fps=1//DeltaTime
    end
    
  • dave1707dave1707 Mod
    Posts: 9,441

    @Simeon Can you explain what’s happening here. The camera image is showing just fine. When you tap the screen to allow img:get to execute, the screen image doesn’t show anymore. By tapping the screen, you can toggle the img:get on and off.

    Also, what’s with the green dot in the upper right corner while the code is running.

    function setup()
        fill(255)
        parameter.watch("fps")
    end
    
    function draw()
        background(0)
        img=image(CAMERA)
        collectgarbage()
        if img ~=nil then
            sprite(img,WIDTH/2,HEIGHT/2,WIDTH,HEIGHT)
            if read then
                r,g,b=img:get(2,2)
            end
        end
        fps=1//DeltaTime
        text("tap screen for img get",WIDTH/2,HEIGHT-50)
    end
    
    function touched(t)
        if t.state==BEGAN then
            read= not read
            print(img)
        end
    end
    
  • Posts: 2,364
    @dave1707 - do you need to specify the opacity as the img:get() call provides r,g,b,a. Does it need all 4 parameters to operate correctly?
  • dave1707dave1707 Mod
    Posts: 9,441

    @Bri_G It doesn’t matter if it’s 3 or 4 values. Do you know what the green dot is for.

  • Posts: 2,364
    #dave1707 - now you've lost me 'green dot' ?
  • dave1707dave1707 Mod
    Posts: 9,441

    @Bri_G When I run the above code, there’s a small green dot in the upper right corner.

  • Posts: 2,364
    @dave1707 - does image:get() number the pixels in the same way as it is displayed?
  • dave1707dave1707 Mod
    Posts: 9,441

    @Bri_G I believe image:get(1,1) is the lower left screen and image:get(WIDTH,HEIGHT) is the upper right.

  • Posts: 2,364

    @dave1707 - I think that the bottom left image get could be 0,0 so is offset by a pixel.

  • dave1707dave1707 Mod
    Posts: 9,441

    @Bri_G If width,height is the size of an img, then

    img:get(1,1) is the lower left.
    img:get(1,height) is the upper left.
    img:get(width,height) is the upper right.
    img:get(width,1) is the lower right.

    img:get(0,0) will give you an out of bounds error.

  • dave1707dave1707 Mod
    Posts: 9,441

    Apparently the green dot in the upper right of the screen is an indicator that the camera is being used. An orange dot means the microphone is being used. So that explains my question from above.

  • Posts: 2,364

    @dave1707 - this device and Codea never cease to amaze me, learn something new every day.

  • dave1707dave1707 Mod
    Posts: 9,441

    @Simeon It appears the placement of the img:get command causes the sprite command not to work. The sprite command isn’t affected with the img:get command after it. If the img:get command is before the sprite command, the sprite doesn’t work. Comment out one ot the othe of the img:get commands. Tap the screen to allow the img:get command to execute.

    viewer.mode=FULLSCREEN
    
    function setup()
    end
    
    function draw()
        background(0)
    
        img=image(CAMERA)
        collectgarbage()
    
        if get then
            --r,g,b=img:get(1,1)
        end
    
        if img~=nil then
            sprite(img,WIDTH/2,HEIGHT/2)
        end
    
        ellipse(400,400,40)
    
        if get then
            r,g,b=img:get(1,1)
        end
    end
    
    function touched(t)
        if t.state==BEGAN then
            get= not get
        end   
    end
    
  • Posts: 2,364
    @dave1707 @Simeon - just a little query on the above code, are the touch and draw functions on separate parallel threads or on a series thread. Also, is this about timing and priorities at the begining of each screen refresh?
  • edited April 16 Posts: 3
    So @dave1707 it doesn’t draw anything to the screen after image:get. It won’t do text or sprites or shapes. I have 3 projects that need to draw something after image:get so this is kind of annoying. Also how do you format code?
  • dave1707dave1707 Mod
    Posts: 9,441

    @possibleAdam To format code here, put 3tildes ~~~ before and after your code. As for the img:get problem, I’m sure it will be fixed soon.

  • SimeonSimeon Admin Mod
    Posts: 5,705
    @dave1707 thanks for the report will look into it
  • dave1707dave1707 Mod
    Posts: 9,441

    @possibleAdam Here’s an example using CAMERA and get/set to alter the image. There image bug isn’t fixed yet, but here’s something that gets around it. Aim the camera at something and tap the screen. Tap the screen again to show a normal live image. You can alter the slider value to change how the image is processed. The lower the value, the more colorful it is. There’s no need to close the parameter window. It will close and open depending on what’s happening.

    viewer.mode=OVERLAY
    
    function setup()
        parameter.integer("div",1,25,10)
    end
    
    function draw()
        background(0)
        img=image(CAMERA)
        collectgarbage()
        if img1~=nil then
            sprite(img1,WIDTH/2,HEIGHT/2)
        elseif img~=nil then
            sprite(img,WIDTH/2,HEIGHT/2)
        end 
    end
    
    function touched(t)
        if t.state==BEGAN then
            if img1~=nil then
                img1=nil
                viewer.mode=OVERLAY
            else
                img1=img:copy()
                iw=img1.width
                ih=img1.height
                process()
            end
        end    
    end
    
    function process()
        viewer.mode=FULLSCREEN
        for x=3,iw,5 do
            for y=3,ih,5 do
                tr,tg,tb=0,0,0
                for a=-2,2 do
                    for b=-2,2 do
                        if (x+a)<iw and (y+b)<ih then
                            r,g,b=img1:get(x+a,y+b)
                            tr=tr+r
                            tg=tg+g
                            tb=tb+b
                        end
                    end
                end
                for a=-2,2 do
                    for b=-2,2 do
                        if (x+a)<iw and (y+b)<ih then
                            img1:set(x+a,y+b,tr//div,tg//div,tb//div)
                        end
                    end
                end
            end
        end
    end
    
  • @dave1707 thank you. Could someone please explain to me again how to format the code. It doesn’t seem to be working.

    I tried this and other variants:

    ~~~
    Code
    ~~~
  • dave1707dave1707 Mod
    Posts: 9,441

    @possibleAdam Where are you posting code from. The tildes only seem to work when using an iPad.

Sign In or Register to comment.