Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Resize CGSize to the maximum with keeping the aspect-ratio

I have a CGSize objects that I need to send to my server. The maximum size I can send to the server is 900*900 (900 width/900 height).

There are some objects that are larger the 900*900 and I want to write a function that resizes them to the maximum (as I already say, the maximum is 900*900) but to keep the aspect ratio.

For example: if I have an object that is 1,000px width and 1,000px height I want the function to return a 900*900 object. If I have an object that is 1920px width and 1080px height I want it to return the maximum size possible with keeping the ratio.

Anyone have any idea how can I do that?

Thank you!

OriginalUser2 answer:

I've tried this code:

let aspect = CGSizeMake(900, 900)
let rect = CGRectMake(0, 0, 1920, 1080)

let final = AVMakeRectWithAspectRatioInsideRect(aspect, rect)

final is {x 420 y 0 w 1,080 h 1,080}, I can't understand why the x = 420, but anyway 1080*1080 is not in the same aspect ratio as 1920*1080 and it's bigger than 900*900.

Can you explain a bit more?

like image 707
F.SO4 Avatar asked Jun 23 '16 15:06

F.SO4


People also ask

How do I find my aspect ratio in UIImage?

size. height * scaleFactor let newWidth = oldWidth * scaleFactor UIGraphicsBeginImageContext(CGSize(width:newWidth, height:newHeight)) sourceImage. draw(in: CGRect(x:0, y:0, width:newWidth, height:newHeight)) let newImage = UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext() return newImage! }


2 Answers

You can use the AVMakeRect(aspectRatio:insideRect:) function from the AVFounation framework in order to do this.

The problem with your code is that the values are round the wrong way. The insideRect: parameter should be the rect to fit your size within, and the aspectRatio: should be the original size that you want to be scaled while maintaining aspect ratio.

For example:

import AVFoundation

// Original size which you want to preserve the aspect ratio of.
let aspect = CGSize(width: 1920, height: 1080)

// Rect to fit that size within. In this case you don't care about fitting
// inside a rect, so pass (0, 0) for the origin.
let rect = CGRect(x: 0, y: 0, width: 900, height: 900)

// Aspect fitted size, in this case (900.0, 506.25)
let result = AVMakeRect(aspectRatio: aspect, insideRect: rect).size
like image 104
Hamish Avatar answered Sep 24 '22 16:09

Hamish


This code can be greatly reduced and modified, but for clarity's sake:

if myImage.width == myImage.height {
    // New image will be 900px by 900px
    newImage.width = (900 / myImage.width) * myImage.width
    newImage.height = (900 / myImage.height) * myImage.height
} else if myImage.width > myImage.height {
    // New image will have width of 900px
    newImage.width = (900 / myImage.width) * myImage.width
    newImage.height = (900 / myImage.width) * myImage.height
} else {
    // New Image will have height of 900px
    newImage.width = (900 / myImage.height) * myImage.width
    newImage.height = (900 / myImage.height) * myImage.height
}

In this snippet, 900 is the maximum width and height of the resized image, but this value can be abstracted with a variable for any value you would like.

like image 41
William Anderson Avatar answered Sep 22 '22 16:09

William Anderson