Magnifying glass

Did anyone try to create a magnifying glass and have Lua code to share?

Here’s an example in ObjectiveC: http://www.craftymind.com/2009/02/10/creating-the-loupe-or-magnifying-glass-effect-on-the-iphone/
I’ve difficulties to see equivalences in CoronaLua, specially regarding the concept of “mask”.
Any help welcomed, thanks.
[import]uid: 8970 topic_id: 3647 reply_id: 303647[/import]

you’d need a mask. we dont have masks yet [import]uid: 6645 topic_id: 3647 reply_id: 11122[/import]

Are masks mandatory to do a magnifying glass? Another way? [import]uid: 8970 topic_id: 3647 reply_id: 11353[/import]

Yes, no
[import]uid: 6645 topic_id: 3647 reply_id: 11358[/import]

Uh, and you’d also need a “screen grab” function that stores the result in memory rather than “on disk”. Otherwise you’d have to wait twice, once for saving and once for loading. With the current grabber it would probably not be a very “responsive” effect. :slight_smile: [import]uid: 5750 topic_id: 3647 reply_id: 11474[/import]

that’s not true. you don’t need to grab anything. you just display the same image again zoomed and with a mask added

[lua]local myImage = display.newImage(“book.png”)
local myMagnifiedImage = display.newImage(“book.png”)
local myMaskImage = display.newImage(“mask.png”)

myMagnifiedImage.xScale=2
myMagnifiedImage.yScale=2

myMagnifiedImage.mask = myMaskImage[/lua]

(note this code won’t work… yet… until ansca add the feature!) [import]uid: 6645 topic_id: 3647 reply_id: 11479[/import]

Why does people always look at *single* things ? - like you having a single bitmap. :slight_smile:
How about having several display objects in hierarchy at different positions and scale on the same screen ? What would you magnify in that “most-of-the-times” case, if you don’t “render-to-texture” the entire stage ? :wink:
[import]uid: 5750 topic_id: 3647 reply_id: 11487[/import]

ok good point erpy. for that we need to be able to “draw” the contents of our display group to a flat bitmap. this feature is possibly on the roadmap [import]uid: 6645 topic_id: 3647 reply_id: 11540[/import]

Exactly, which isn’t that different from the current “take screenshot”… just, as said, needs to be faster - i.e. saved straight to memory.

This is commonly known as “render to texture” in 3D realtime… and since Corona is OpenGL-based sounds like an appropriate term. :slight_smile: [import]uid: 5750 topic_id: 3647 reply_id: 11562[/import]

Hi,

I’ve been thinking about this and the only way I can see of doing it currently is to have a stationary touch event cause a screen grab into the app’s resource directory; then to open a web popup near the touch with a customised, local web page which accepts parameters to load the screen grab, position and scale it appropriately using the touch coordinates.

I don’t know if the web popup could be moved relative to the touch or if touch events stop getting passed to the corona app when the touch moves onto the web popup, but I’ve done the photoshop/html/css work to produce a magnifier which loads the scaled image.

https://files.me.com/horacebury/cxj2us

I hope someone can finish the corona code, I’m going to bed and can’t work on this for a while.

Matt. [import]uid: 8271 topic_id: 3647 reply_id: 11648[/import]

ok here’s a (very rough) magnifying glass using capture screen, but it’s late and i can’t work out the maths to scale the movement. I didnt understand the need for the web popup in your example though

a couple of things to note

* the screen capture is scaled, then masked
* scaling the capture seems to scale the mask (bug?)
* the screen capture would also actually need to move based on the scale, otherwise you end up with the lens showing the wrong thing underneath. i’ve not implemented this. basically since i’ve magnified from the centre, as you move towards the edge the magnified bit is further away.
* it doesn’t scale correctly when viewing as iPhone4 etc… need to modify some of the calculations config etc i think

if someone could post any fixes that would be great

the end target would be to have it re-capture the display anytime the user clicks on the screen/magnifying glass etc. this would mean that the main original screen would need to be static (not updating) until you let go again. essentially you’re just viewing a screen capture.

also you’d probably want to overlay the graphic of a magnifying glass at the same position as the mask. it probably gets more complicated if you try to start putting them in display groups together, as the mask isnt a separate image as such , it’s a part of the scaled image here
regards
J

[lua]display.setStatusBar( display.HiddenStatusBar )

local halfW = display.contentCenterX
local halfH = display.contentCenterY

local W = display.contentWidth
local H = display.contentHeight

local canvas = display.newGroup()

local rnd = math.random

for i=1, 200, 1 do
local line = display.newLine(rnd()*W, rnd()*H, rnd()*W, rnd()*H)
line:setColor(rnd()*255,rnd()*255,rnd()*255)
canvas:insert(line)

local box = display.newRect(rnd()*W, rnd()*H, 2+rnd()*50, 2+rnd()*50)
box:setFillColor(rnd()*255,rnd()*255,rnd()*255)
canvas:insert(box)
end

local canvascopy = display.captureScreen()

local SCALE_RATIO = 2

canvascopy.xScale=SCALE_RATIO
canvascopy.yScale=SCALE_RATIO

local mask = graphics.newMask( “circlemask.png” )
canvascopy:setMask(mask)

canvascopy.maskScaleX=1/SCALE_RATIO
canvascopy.maskScaleY=1/SCALE_RATIO

function onTouch( event )
print(“touch”)
local t = event.target

local phase = event.phase
if “began” == phase then
display.getCurrentStage():setFocus( t )

– Spurious events can be sent to the target, e.g. the user presses
– elsewhere on the screen and then moves the finger over the target.
– To prevent this, we add this flag. Only when it’s true will “move”
– events be sent to the target.
t.isFocus = true

– Store initial position
t.x0 = (event.x - t.maskX*SCALE_RATIO)
t.y0 = (event.y - t.maskY*SCALE_RATIO)

elseif t.isFocus then
if “moved” == phase then
– Make object move (we subtract t.x0,t.y0 so that moves are
– relative to initial grab point, rather than object “snapping”).
t.maskX = (event.x - t.x0)/SCALE_RATIO
t.maskY = (event.y - t.y0)/SCALE_RATIO
elseif “ended” == phase or “cancelled” == phase then
display.getCurrentStage():setFocus( nil )
t.isFocus = false
end
end

return true
end

canvascopy:addEventListener( “touch”, onTouch )[/lua] [import]uid: 6645 topic_id: 3647 reply_id: 21106[/import]

Good work!

The web popup in my code was because we didn’t have masking back then.

M [import]uid: 8271 topic_id: 3647 reply_id: 21117[/import]

can anyone help solve this please? the inverse ratios combined with the fact that the mask is scaled with the zoomed layer is throwing me!

i’ve put the cap in a group and overlaid a circle to show the group moving but the screencap not moving to where it needs to be. t.canvascap.maskX needs to be changed based on the zoom ratio etc and I can’t work that out.

thanks
j

[lua]display.setStatusBar( display.HiddenStatusBar )

local halfW = display.contentCenterX
local halfH = display.contentCenterY

local W = display.contentWidth
local H = display.contentHeight

print(W,H)

local lines={}

local canvas = display.newGroup()

local rect=display.newRect(0,0,display.contentWidth, display.contentHeight)
rect:setFillColor(0,0,0)
canvas:insert(rect)
local rnd = math.random

for i=1, 200, 1 do
local line = display.newLine(rnd()*W, rnd()*H, rnd()*W, rnd()*H)
line:setColor(rnd()*255,rnd()*255,rnd()*255)
canvas:insert(line)

local box = display.newRect(rnd()*W, rnd()*H, 2+rnd()*50, 2+rnd()*50)
box:setFillColor(rnd()*255,rnd()*255,rnd()*255)
canvas:insert(box)
end

local canvascap = display.captureScreen()

canvascopy = display.newGroup()
local SCALE_RATIO = 2

canvascap.xScale=SCALE_RATIO
canvascap.yScale=SCALE_RATIO
local mask = graphics.newMask( “circlemask.png” )
canvascap:setMask(mask)

canvas.alpha=0.7
canvascopy.alpha=1

canvascap.maskScaleX=1/SCALE_RATIO
canvascap.maskScaleY=1/SCALE_RATIO
canvascopy.canvascap = canvascap
canvascopy:insert(canvascap)
canvascopy.isHitTestable=true

local circ = display.newCircle(halfW, halfH, 100)
circ.alpha=0.25
canvascopy:insert(circ)

function onTouch( event )
–print(“touch”)
local t = event.target

local phase = event.phase
if “began” == phase then
display.getCurrentStage():setFocus( t )

t.isFocus = true

– Store initial position
t.x0 = (event.x - t.x)
t.y0 = (event.y - t.y)

elseif t.isFocus then
if “moved” == phase then
– Make object move (we subtract t.x0,t.y0 so that moves are
– relative to initial grab point, rather than object “snapping”).

t.x = event.x - t.x0
t.y = event.y - t.y0

– t.canvascap.maskX = (event.x - t.x0)
– t.canvascap.maskY = (event.y - t.y0)

elseif “ended” == phase or “cancelled” == phase then
display.getCurrentStage():setFocus( nil )
t.isFocus = false
end
end

return true
end

canvascopy:addEventListener( “touch”, onTouch )[/lua]
[import]uid: 6645 topic_id: 3647 reply_id: 21267[/import]

Here is a modification that seems to work a bit better (at least for my purposes)

http://db.tt/veZ3pLG

The trick & change from the original is you need to move the background canvas in the opposite direction so the circlemask is always ‘magnifying’ the correct visible portion – a small change but provides a more convincing result (my project file includes a picture so you can visually see it’s lining up better)

There are still a few problems (the magnifier flies off screen on second click) and it doesn’t work right for scale factors > 2 but as I said it seems to do a more convincing magnification

Thanks to the orginal poster actually mentioned this so this is just a (very small) clean up of that

-John

[import]uid: 48162 topic_id: 3647 reply_id: 29957[/import]

I got a (IMHO) good one: http://developer.coronalabs.com/code/magnifying-glass [import]uid: 8271 topic_id: 3647 reply_id: 115305[/import]