How to crop a scaled picture?

For example, I have a picture and its size is

900x600

and I want to put this picture into a box, which is 150x150 (different width/height ratio than the original picture)

What to do to generate a 150x150 picture from the original picture without distortion? (some picture contents can be cropped, it’s ok)

I made this crop function you could use. In example at bottom I’m using a red rect, just use display.newImage instead of the rect.

[lua]

local function crop(photo, newFileName)

    

    – End size we want

    local endWidth  = 256

    local endHeight = 256

    

    local tempGroup = display.newGroup()

    

    photo.x = display.contentCenterX

    photo.y = display.contentCenterY

    tempGroup:insert(photo)

    

    – Find the bigger scale out of widht or height so it will fill in the crop

    local scale = math.max(endWidth / photo.width, endHeight / photo.height)

    

    photo:scale(scale, scale)

    

    – This object will be used as screen capture boundaries object

    local cropArea = display.newRect(display.contentCenterX, display.contentCenterY, endWidth, endHeight)

    cropArea.x     = display.contentCenterX

    cropArea.y     = display.contentCenterY

    cropArea       : setReferencePoint(display.CenterReferencePoint)

    cropArea.alpha = 0.0

    tempGroup:insert(cropArea)

    

    – Now capture the crop area which the user image will be underneith

    local myCaptureImage = display.captureBounds(cropArea.contentBounds)

    display.save(myCaptureImage, newFileName) 

    --myCaptureImage:removeSelf() – Remove captured image

    --myCaptureImage = nil

    

    tempGroup:removeSelf()

    tempGroup = nil

end

local photo = display.newRect(10,10,100,400)

photo:setFillColor(255,0,0)

– Put cropped photo into documents directory

crop(photo, “cropped.png”)

[/lua]

@jonjonsson

Thanks a lot, you are the man.

Joe, as per reply from @mpappas here http://forums.coronalabs.com/topic/38651-change-size-of-displaysave-image/

I think its a good idea to modify line 4 and 5 to:

[lua]

local endWidth  = 256 * display.contentScaleX

local endHeight = 256 * display.contentScaleY

[/lua]

That way the image is always 256px w/h no matter the device.

Hi Jon

What does it mean? If I made the changes you suggested, the picture I got is much smaller, which is not the end size I really want.

…[some research & thinking]…

But I think I got it after a second thought. I think it doesn’t apply to my case because I want the end size to be scaled according to different devices.

Thanks a lot for reminding me of this.

Joe

OK, I’m uploading the image so I want the physical size of the images to be consistent. If you are displaying them, then better skip that modification.

hi, Jon

I saw he also mentioned 

Depending on which capture API you are using, you might notice some edge artifacts though (if the final dimensions aren’t a multiple of 4 pixels).

And I do see this kind of artifact edge in some of my rendered images. 

Do you know any method to solve this? (If my final dimensions aren’t a multiple of 4 pixels)

Have you tried cropping in a multiple of 4 and then resize to desired size?

I adjusted the final image size to be a multiple of 4, then it’s ok

I thought it’s ok, but after a few days observations, some of the pictures still have artifact edges… although I have adjusted the final size to be a multiple of 4 pixels…  :frowning:

Thanks a lot, this was really useful for me right now :slight_smile:

I found the artifacts edges might appear/disappear when using different devices

I am using “ZoomEven”

I am wondering if the final size has to be calculated with something else, like the viewable height/width

Try the modification I mention above:

[lua]

local endWidth  = 256 * display.contentScaleX

local endHeight = 256 * display.contentScaleY

[/lua]

Then rescale the resulting image.

I made this crop function you could use. In example at bottom I’m using a red rect, just use display.newImage instead of the rect.

[lua]

local function crop(photo, newFileName)

    

    – End size we want

    local endWidth  = 256

    local endHeight = 256

    

    local tempGroup = display.newGroup()

    

    photo.x = display.contentCenterX

    photo.y = display.contentCenterY

    tempGroup:insert(photo)

    

    – Find the bigger scale out of widht or height so it will fill in the crop

    local scale = math.max(endWidth / photo.width, endHeight / photo.height)

    

    photo:scale(scale, scale)

    

    – This object will be used as screen capture boundaries object

    local cropArea = display.newRect(display.contentCenterX, display.contentCenterY, endWidth, endHeight)

    cropArea.x     = display.contentCenterX

    cropArea.y     = display.contentCenterY

    cropArea       : setReferencePoint(display.CenterReferencePoint)

    cropArea.alpha = 0.0

    tempGroup:insert(cropArea)

    

    – Now capture the crop area which the user image will be underneith

    local myCaptureImage = display.captureBounds(cropArea.contentBounds)

    display.save(myCaptureImage, newFileName) 

    --myCaptureImage:removeSelf() – Remove captured image

    --myCaptureImage = nil

    

    tempGroup:removeSelf()

    tempGroup = nil

end

local photo = display.newRect(10,10,100,400)

photo:setFillColor(255,0,0)

– Put cropped photo into documents directory

crop(photo, “cropped.png”)

[/lua]

@jonjonsson

Thanks a lot, you are the man.

Joe, as per reply from @mpappas here http://forums.coronalabs.com/topic/38651-change-size-of-displaysave-image/

I think its a good idea to modify line 4 and 5 to:

[lua]

local endWidth  = 256 * display.contentScaleX

local endHeight = 256 * display.contentScaleY

[/lua]

That way the image is always 256px w/h no matter the device.

Hi Jon

What does it mean? If I made the changes you suggested, the picture I got is much smaller, which is not the end size I really want.

…[some research & thinking]…

But I think I got it after a second thought. I think it doesn’t apply to my case because I want the end size to be scaled according to different devices.

Thanks a lot for reminding me of this.

Joe

OK, I’m uploading the image so I want the physical size of the images to be consistent. If you are displaying them, then better skip that modification.

hi, Jon

I saw he also mentioned 

Depending on which capture API you are using, you might notice some edge artifacts though (if the final dimensions aren’t a multiple of 4 pixels).

And I do see this kind of artifact edge in some of my rendered images. 

Do you know any method to solve this? (If my final dimensions aren’t a multiple of 4 pixels)

Have you tried cropping in a multiple of 4 and then resize to desired size?