3

I'm using AlamofireImage to download and set my UIImage:

backdrop.af_setImageWithURL(downloadURL)

The image is substantially larger than what I will be displaying and so I have an issue with aliasing. How can I resize this image properly?

Results:

enter image description here

Zoe
  • 27,060
  • 21
  • 118
  • 148
mrmike
  • 398
  • 2
  • 4
  • 14
  • Can you tell us what have you done so far and it's not working, so that we can help you out. Because as the question is looking now it can be categorised as opinion based and is not suitable for this forum. – Andrej Jun 27 '16 at 20:10
  • I haven't done anything regarding anti-aliasing, I don't know how to. My image displays perfectly fine apart from the aliasing. @Andrej – mrmike Jun 27 '16 at 20:13
  • What is your issue re aliasing? Most resizing algorithms are likely to yield the same effect. Re general resizing algorithms, see http://stackoverflow.com/a/28513086/1271826. Generally we're resizing to minimize memory impact, though, not to tackle any softening of the image due to changing its size. – Rob Jun 27 '16 at 20:32
  • BTW, Alamofireimage already has image [scaling methods](https://github.com/Alamofire/AlamofireImage#scaling), so you probably don't need to write your own. – Rob Jun 27 '16 at 20:37
  • I have already described my issue regarding aliasing to the best of my ability, the only way I can describe it is that it looks too sharp. Fine lines that are close together don't look right. I feel that the image does need to be softer. I used the 'Aspect Fit' mode in storyboard to scale my image. I will post before and after pictures using the accepted solution so that you can see. @Rob – mrmike Jun 27 '16 at 23:34

2 Answers2

7

You can resize the image with any size once you have a valid UIImage:

func resizedImageWith(image: UIImage, targetSize: CGSize) -> UIImage {

    let imageSize = image.size
    let newWidth  = targetSize.width  / image.size.width
    let newHeight = targetSize.height / image.size.height
    var newSize: CGSize

    if(newWidth > newHeight) {
        newSize = CGSizeMake(imageSize.width * newHeight, imageSize.height * newHeight)
    } else {
        newSize = CGSizeMake(imageSize.width * newWidth,  imageSize.height * newWidth)
    }

    let rect = CGRectMake(0, 0, newSize.width, newSize.height)

    UIGraphicsBeginImageContextWithOptions(newSize, false, 0.0)

    image.drawInRect(rect)

    let newImage = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()

    return newImage
}

For any other queries/modifications you have, refer this NShipster

Santosh
  • 2,900
  • 1
  • 16
  • 16
  • 1
    Agreed! Yes when we set the `scale` to 0.0 then the main screen's scale would be used which is 2.0 or more for Retina screens. Updated my answer. – Santosh Jun 27 '16 at 20:33
  • I would also scale it down with UIJPEGRepresentation(image, amountToScale0Through1) – Sethmr Jun 27 '16 at 21:07
  • @Sethmr - `UIImageJPEGRepresentation` doesn't do any scaling. All it does is convert `UIImage` to `NSData` (either making the asset much larger or shrinking it but introducing JPEG artifacts in the process). There are times you need `UIImageJPEGRepresentation`, but there's nothing in this question to suggest that's what's needed here. – Rob Jun 27 '16 at 23:39
  • I am sure that it reduces the file size. I guess I misinterpreted what was needed. – Sethmr Jun 28 '16 at 01:22
  • @sethmr - Yep, you can use a quality setting below 1.0 to reduce file size, but it doesn't scale the image, but rather applies a lossy compression (i.e. degrades image quality, introducing artifacts, barely noticeable at values of 0.8 or 0.9, but visually noticeable at lower values). It's useful when trying to reduce size of image that is, for example, being uploaded to web service, but doesn't reduce run-time memory usage of `UIImage`. To achieve run-time memory savings, you have to scale image, like shown in Santosh's answer (or use Alamofireinage scaling methods, which do the same thing). – Rob Jun 28 '16 at 05:52
1

Here is @Santosh's answer in ObjC:

- (UIImage*) scaleImage:(UIImage*)image toSize:(CGSize)newSize {

    CGSize imageSize = image.size;
    CGFloat newWidth  = newSize.width  / image.size.width;
    CGFloat newHeight = newSize.height / image.size.height;
    CGSize newImgSize;

    if(newWidth > newHeight) {
        newImgSize = CGSizeMake(imageSize.width * newHeight, imageSize.height * newHeight);
    } else {
        newImgSize = CGSizeMake(imageSize.width * newWidth,  imageSize.height * newWidth);
    }

    CGRect rect = CGRectMake(0, 0, newImgSize.width, newImgSize.height);

    UIGraphicsBeginImageContextWithOptions(newImgSize, false, 0.0);

    [image drawInRect:rect];;

    UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    return newImage;
}
Jameson
  • 4,198
  • 4
  • 17
  • 31