Howdy, Stranger!

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

Camera on the fly filter

Hi, i am a newbie here. Testing the camera demo app. Is it possible to add filters on the fly? Like showing black and white image, or only red channel.?
Thanks

Comments

  • dave1707dave1707 Mod
    edited October 2016 Posts: 7,612

    Yes you can. Using shaders is one way, but since you're a newbie you probably don't have shader experience. I don't have time right now to go into more detail but you can do a forum search to see what you can find.

    EDIT: Try a forum search for camera filters.

  • IgnatzIgnatz Mod
    edited October 2016 Posts: 5,396

    No, although I'm sure someone has probably written code for that kind of thing.

    Having said that, check out the blend function, discussion here
    https://codea.io/talk/discussion/4989/blendmodes

    And code here
    https://gist.github.com/anonymous/6b42853df4823cd326ba

    If blend doesn't do it, you will probably need to use a shader to do fast pixel manipulation. You can get some help with that if you post your exact requirements.

  • dave1707dave1707 Mod
    edited October 2016 Posts: 7,612

    @aamato Here's something to play with.

    EDIT: Made some changes to the code.
    EDIT: Changed the way rgb is averaged.

    function setup() 
        parameter.number("red",0,1,0)
        parameter.number("green",0,1,0)
        parameter.number("blue",0,1,0)
        parameter.integer("grey",0,1,0)
        m=mesh()
        m:addRect(WIDTH/2,HEIGHT/2,WIDTH,HEIGHT)
        m:setColors(color(255,255,255))
        m.shader=shader(DefaultShader.vertexShader,DefaultShader.fragmentShader)
    end
    
    function draw() 
        background(40, 40, 50) 
        img=image(CAMERA)
        if img~=nil then
            collectgarbage()
            m.texture=img 
            m.shader.red=red 
            m.shader.green=green 
            m.shader.blue=blue 
            m.shader.grey=grey 
            m:draw()
        end
    end
    
    DefaultShader = 
        {   vertexShader = [[
            precision highp float;
            uniform mat4 modelViewProjection;
            attribute vec4 position; 
            attribute vec4 color; 
            attribute vec2 texCoord;
            varying vec4 vColor; 
            varying vec2 vTexCoord;
            void main() 
            {   vColor=color;
                vTexCoord = texCoord;
                gl_Position = modelViewProjection * position;
            }    ]],
    
            fragmentShader = [[
            precision highp float;
            uniform sampler2D texture;
            varying vec4 vColor; 
            varying vec2 vTexCoord;
            uniform float red;
            uniform float green;
            uniform float blue;
            uniform float grey;   
            void main() 
            {   vec4 col = texture2D( texture, vTexCoord) * vColor;
                col.r=col.r+red-green-blue;        // changed
                col.g=col.g+green-red-blue;      // changed
                col.b=col.b+blue-red-green;      // changed
                if (grey == 1.0)
                { float avg=0.0;
                   avg=col.r*.21+col.g*.72+col.b*.07;     // changed
                 //avg=(col.r+col.g+col.b)/3.0;
                  col.r=avg;
                  col.g=avg;
                  col.b=avg;
                }
                gl_FragColor = col; 
            }    ]]
        }
    
  • @dave1707 Why can't you use tint? It seems to work unless you need greyscale.

  • dave1707dave1707 Mod
    Posts: 7,612

    @MattthewLXXIII You can use tint, but like you said, greyscale doesnt give a black/white image. @aamato also wanted black and white and the shader wasn't hard to use.

  • dave1707dave1707 Mod
    Posts: 7,612

    @ignatz I changed the above code to use luminosity averaging. There was just a slight difference, but lumonisity was a little better.

  • IgnatzIgnatz Mod
    edited October 2016 Posts: 5,396

    :)

  • Posts: 13

    @dave1707 amazing. Thank you. I am impressed with the tool, and the responsiveness of this forum. Thank everyone.

  • IgnatzIgnatz Mod
    Posts: 5,396

    @aamato - if you substitute this shader for Dave's, I think it may give a truer picture of the red, green or blue components of the image. Slide R,G or B values to 1 to see a colour, 0 to exclude it. B/W works as before.

    DefaultShader = 
        {   vertexShader = [[
            precision highp float;
            uniform mat4 modelViewProjection;
            attribute vec4 position; 
            attribute vec4 color; 
            attribute vec2 texCoord;
            varying vec4 vColor; 
            varying vec2 vTexCoord;
            void main() 
            {   vColor=color;
                vTexCoord = texCoord;
                gl_Position = modelViewProjection * position;
            }    ]],
    
            fragmentShader = [[
            precision highp float;
            uniform sampler2D texture;
            varying vec4 vColor; 
            varying vec2 vTexCoord;
            uniform float red;
            uniform float green;
            uniform float blue;
            uniform float grey;   
            void main() 
            {   vec4 col = texture2D( texture, vTexCoord) * vColor*vec4(red,green,blue,1);
                if (grey == 1.0)
                { float avg=0.0;
                   avg=col.r*.21+col.g*.72+col.b*.07;     // changed
                 //avg=(col.r+col.g+col.b)/3.0;
                  col.r=avg;
                  col.g=avg;
                  col.b=avg;
                }
                gl_FragColor = col; 
            }    ]]
        }
    
  • Posts: 13

    Amazing people. thanks. Working with img=image(CAMERA) is it possible to add text or an overlay image in the front of the camera?

  • IgnatzIgnatz Mod
    Posts: 5,396

    Of course.

    Just do that at the end of the draw function, after drawing the camera image (which is a static image so you can draw over it).

  • dave1707dave1707 Mod
    Posts: 7,612

    @aamato In my code above, the img from the camera is updated 60 times per second. Since that is constantly changing, you can't draw on that image itself. You can draw on the screen so it looks like you're drawing on the image, but once you move the camera, you'll still have what you drew on the screen, but the camera image will be different. If you want to actually draw on the camera image, then the above code will have to change.

  • dave1707dave1707 Mod
    Posts: 7,612

    @aamato Here's an example of a program that will let you capture an image and then draw on it. Move the camera around until you get the image you want, double tap the screen to capture the image, then draw on the image.

    displayMode(FULLSCREEN)
    
    function setup() 
        tab={}
    end
    
    function draw() 
        background(40, 40, 50) 
        fill(255)
        if img~=nil then
            sprite(img,WIDTH/2,HEIGHT/2)
        end
        if not done then
            text("Double tap the screen to capture an image.",WIDTH/2,HEIGHT-20)
            img=image(CAMERA)
            collectgarbage()
        end
        for a,b in pairs(tab) do
            ellipse(b.x,b.y,15)
        end
    end
    
    function touched(t)
        if t.state==BEGAN and t.tapCount==2 and not done then
            img=image(CAMERA)
            done=true
        end
        if t.state==MOVING and done then
            table.insert(tab,vec2(t.x,t.y))
        end
    end
    
  • @dave1707 what do you use collectgarbage() for, and what does it mean when you call it without arguments?

  • JohnJohn Admin Mod
    Posts: 573

    Just so you know, you can set mesh.texture directly to CAMERA and it doesn't need image() or garbage collection.

  • dave1707dave1707 Mod
    Posts: 7,612

    @John I tried CAMERA with mesh.texture without calling garbagecollection and Codea crashed after about 5 seconds.

  • dave1707dave1707 Mod
    Posts: 7,612

    @John Ignore the previous post. I forgot to remove the img=image(CAMERA) statement. Once I remove it, Codea ran fine.

  • Posts: 13

    Very interesting. I am amazed by the fact of how easy it is to do complex things in other languages, but so difficult to do simple things in other languages. I mean, creating buttons, sliders, windows ... I am studying soda, seems the right solution. But still regarding the camera question. Is it possible to override the standard photo and movie buttons for my own?

  • Posts: 2,020
    > Is it possible to override the standard photo and movie buttons for my own?

    You mean the buttons in the bottom left of the screen? No you can't change their appearance or performance. You can hide them and then, for the screenshot button at least, implement something similar.
Sign In or Register to comment.