image:copy Question

I’m taking a photo and copying a 500 x 500 pixel section out of the center of it. I’m having trouble with the parameters for image:copy. The documentation says that the Y parameter is “y location of the topmost pixels of the copy region” and that X is “location of the leftmost pixels of the copy region,” But, I can’t get the numbers to work out. I’m working from the center of the screen for everything except copy (as I can’t find a CENTER mode for it) and it seems the math should be simple. If I use HalfHeight - 250, I get somewhat better results. The commented out line will work but the numbers don’t seem related to anything.

The structure is a bit convoluted as I want to pull the appropriate functions to put into a game that I’m working on and because I’m a newbie. Many thanks in advance!

-- TakePhoto

displayMode(FULLSCREEN)

function setup()
    PhotoSetup()
end

function PhotoSetup()
    rectMode( CENTER )
    spriteMode( CENTER )
    textMode( CENTER )
    cameraSource( CAMERA_FRONT )
    HalfWidth = WIDTH * .5
    HalfHeight = HEIGHT * .5
    Status = "Posing"    
end

function PosePhoto()
        sprite( CAMERA, HalfWidth, HalfHeight ) -- Show what's on camera 
        noFill()
        strokeWidth( 5 )
        rect( HalfWidth, HalfHeight, 500, 500 )  -- Create frame
        fill ( 0 )
        rect ( HalfWidth, HEIGHT - 50, WIDTH, 100 ) -- Box for instruction
        fill( 255 )
        fontSize ( 24 )
        text( "Center your face in the frame and tap the screen to take your photo.", HalfWidth, HEIGHT - 50 )
end

function TakePhoto()
    Photo = image( CAMERA ) -- Take Photo
    CroppedPhoto = Photo:copy( HalfWidth - 250, HalfHeight + 250, 500, 500 ) 
--    CroppedPhoto = Photo:copy( HalfWidth - 100, HalfHeight - 280, 500, 500 )
end

function draw() 
    background( 40, 40, 50 )
    if Status == "Posing" then
        PosePhoto()
    elseif Status == "ShowPhoto" then
        sprite ( CroppedPhoto, HalfWidth, HalfHeight )
    end
end

function touched(t)
    TakePhoto()
    Status = "ShowPhoto"
end

@DaveW Try this line.


    CroppedPhoto = Photo:copy( (HalfWidth-250), (HalfHeight-125), 500, 500 ) 

@dave1707. No, that is still off. Thanks.

@DaveW If I use that line of code and center my face in the square, when I take the picture, that’'s what I see. How far is it off for you.

@dave1707. My face is in the lower right quarter of the frame. I have a Retina screen. Could that make a difference? Thanks again for all your help!

@DaveW I’m using an iPad Air which has a Retina screen. The difference is I’m running Codea version 2.0 which you don’t have. Could you run this sample code. Put what you want to take in the square in the lower left corner of the screen. Press the “Take picture” button. Is the picture taken the same as what you saw. My other iPad is an iPad1 which doesn’t support the camera, so I can’ try this on there. If the image isn’t correct, let me know which way it’s off. There might be a difference in the new version.


function setup()
    spriteMode(CORNER)
    parameter.action("Front Camera",function() cameraSource(CAMERA_FRONT) end)
    parameter.action("Back Camera",function() cameraSource(CAMERA_BACK) end)
    parameter.action("Take picture",xxx)
    parameter.action("Clear",function() img=nil end)
    cameraSource(CAMERA_BACK)
end

function draw()
    background(40, 40, 50)
    if img~=nil then
        sprite(img,0,0)
    else
        sprite(CAMERA,0,0)  
    end  
    noFill()
    stroke(255)
    strokeWidth(4)
    rect(0,0,300,300)
end

function xxx()
    i=image(CAMERA)
    img=i:copy(0,0,300,300)   
end

@dave1701, This works! An oddity is that when I start it from Air Code, it it mirror imaged but when I start it from the iPad it’s OK. Curious but manageable! Is the difference that you are using corners? Thanks.

@DaveW I think the spriteMode(CORNER) has a lot to do with it. Also, it looks like the x,y position of image copy() is really the lower left corner, not the upper left corner.

@DaveW One thing you have to keep in mind when using the camera is the size of the image. The back camera shows an image size of 1080 x 1920 pixels in portrait and 1920 x 1080 pixels in landscape. The front camera shows an image size of 720 x 1280 pixels in portrait and 1280 x 720 pixels in landscape. The screen size is 768 x 1024 in portrait and 1024 x 768 in landscape. When you display the camera image using spriteMode(CENTER), then part of the image is off the screen. So when you try to do a image:copy(0,0,?,?), then you’re copying part of the image that’s off the screen. If you do spriteMode(CORNER) then the 0,0 position of the image is in the lower left corner of the screen. So when you do an image:copy(0,0,?,?), then the area you see on the screen is the area you get from the copy.

@dave1707, That makes some sense. I’ll try rewriting to use CORNER and see what happens. If there were a CENTER mode for copy, would my current code work OK? Thanks a lot for all the help.

@DaveW I’m sure if there were a CENTER mode for copy it would work, but that will probably never happen. Since I gave you the dimensions of the camera image and the dimensions of the screen, it wouldn’t be any problem at all to write a few lines of code that will simulate a CENTER copy.