How to get a selection of an image [ANSWERED]

Is it possible to get a selection of an image instead of not getting the whole image? Is that what image.get is? If so please tell me how.

Not possible currently, you can only get one point at a time with get or the whole thing with copy. Although folks have requested this exact feature and i’m sure it’s on the list somewhere.

Hmmm. What do you want to do with the selection?

images are always rectangular, but like the sprites, they support full alpha blending - so having, for example, a circular image isn’t impossible, but you’ll need to do it yourself. Just set the alpha of the pixels you don’t want to zero.

-- img is my image I've already drawn in with setContext and so on
for x=1, img.width do
   for y=1, img.height do
      if (((x-img.width/2)^2 + (y-img.width/2)^) > 100) then -- that's x^2+y^2>r^2
         img.set(x, y, 0, 0, 0, 0)

CAVEAT: Typed that straight, didn’t try it. Minor syntax errors may be there.

Idea is - look at each pixel of the image, if it shouldn’t be there (In this case, if it’s outside a circle of 10 radius centered in the middle of the image), set it’s alpha to 0. I set the whole thing to 0, actually, but you could image.get the colors to do things like fade rather than just cut off.

You can then use sprite() to draw your image where you want, and it’ll “stamp” onto the surface.

Thinking about it - that’s the general case. If you just want a sub-rectangle, use clip() and setContext().

@Zoyt you can use image:copy to copy a sub-section of an image into another image.

setContext() is not available until 1.2.7.

Great. Thanks.

@Simeon - Is there an example that uses image:copy? Thanks.

You can use it like this:

myImage = image(400, 400)

-- copy the lower left quadrant of myImage into subImage
subImage = myImage:copy(0, 0, 200, 200) 

It doesn’t seem to work with sprites.

Yeah that will have to wait for setContext() to be able to be done properly. However you can try the following function:

function drawClippedSprite( spriteName, position, clipX, clipY, width, height )
    clip( position.x + clipX, position.y + clipY, width, height )

    sprite( spriteName, position.x, position.y )


Unfortunately it won’t respect the current transformation matrix (translate, scale, rotate will cause issues).

Great. Thank you. I am looking forward to apple approving your update.

Simon, was image:copy(x,y,w,h) release after image:copy() ?

I remember looking for the version with arguments, not finding it and even seeing a comment on the forum. Maybe it was all a dream…

Ah i think my brain is just on holiday already. What we dont have is the ability to copy a smaller image onto a section of a bigger one (until the next version that is)

Yes - that’s what setContext() makes easy.

For the adventurous (why waste nearly obsolete code) - here’s Pic:stamp, easily modified to do this until setContext() makes it obsolete:

function Pic:stamp(dest, x, y)
    local sx, sy, sr, sg, sb, sa, dr, dg, db, da
    local rr, rg, rb, ra
    for sx=1, self.width do
        for sy=1, self.height do
            sr, sg, sb, sa = self.image:get(sx, sy)
            dr, dg, db, da = dest.image:get(x+sx-1, y+sy-1)
            sa = sa/255
            da = da/255
            local am = 1-sa
            ra = sa + da*am
            rr = (sr + dr*am)/ra
            rg = (sg + dg*am)/ra
            rb = (sb + db*am)/ra
            if (ra == 0) then
                rr, rg, rb = 0, 0, 0
            dest.image:set(x+sx-1, y+sy-1, rr, rg, rb, ra*255)    

Alpha-blending FTW!

I quite literally wrote the above THE SAME DAY Simeon put setContext() into the beta - just earlier. :slight_smile:

Oh… Cool! That will be helpful!