0

I am receiving an image from backend that is of a large size as i have to place the same image as profile picture and show the same image on bottom bar in tab bar of size 30x30. I tried to scale down image in various ways but nothing is working.

Tried Alamofire's method which also didn't worked(the image appears to be blurred and distorted):

func resizeImageWithoutDistortion(image: UIImage, size : CGSize) -> UIImage{


    // 1. Scale image to size disregarding aspect ratio
    let scaledImage = image.af_imageScaled(to: size)

    // 2. Scale image to fit within specified size while maintaining aspect ratio
    let aspectScaledToFitImage = image.af_imageAspectScaled(toFit: size)

    // 3. Scale image to fill specified size while maintaining aspect ratio
    let aspectScaledToFillImage = image.af_imageAspectScaled(toFill: size)

    return scaledImage.roundImage()
}

Also tried as follows which also didn't worked:

func resizeImage(_ newWidth: CGFloat) -> UIImage {

        let ratio = size.width / size.height
        if ratio > 1 {
            UIGraphicsBeginImageContext(CGSize(width: newWidth, height: newWidth))
            draw(in: CGRect(x: newWidth * ratio / 2 - newWidth, y: 0, width: newWidth * ratio, height: newWidth))
            let newImage = UIGraphicsGetImageFromCurrentImageContext()
            UIGraphicsEndImageContext()

            return newImage!.roundImage()
        } else {
            UIGraphicsBeginImageContext(CGSize(width: newWidth, height: newWidth))
            draw(in: CGRect(x: 0, y: (newWidth / ratio - newWidth) / 2 * (-1), width: newWidth, height: newWidth / ratio))
            let newImage = UIGraphicsGetImageFromCurrentImageContext()
            UIGraphicsEndImageContext()

            return newImage!.roundImage()
        }
    }

In the screenshot the image in bottom is very distorted.enter image description here

Ishika
  • 2,187
  • 1
  • 17
  • 30
  • Please update your post with what you mean by it is not working, and while you are at it include a question (this is a Q&A site, not a V&S (Vague-description&Suggestion site) . You should also indicate in detail what the original images look like, because, unless you start with high-resolution-but-low-detail images, you cannot scale them down to 30x30 without quality loss (and the associated distortion. e.g. by describing that the high resolution images are blown up from 30x30 images originally. – Anthon Aug 27 '17 at 18:27
  • Hi, I have added the screenshot and all I want is maintain the quality of the image both in profile picture and bottom bar. – Ishika Aug 27 '17 at 18:32
  • I assume UIImage should do that from itself. Simply do not resize the image. Let it stay that big and use aspect fill. To make an image round use the layer of the UIImage and round that instead of really manipulating the image. That is a really costly operation. Make sure to set the aspect to 1:1 on that image view. – bemeyer Aug 27 '17 at 20:21

1 Answers1

0

Ishika, your problem is not the quality loss. Your problem is that you don't take the iOS Scaling into consideration.

Points and Pixels are not the same thing.

If you have an UIImageView in W: 30 H: 30 (points) to calculate your Image in pixels to show it clearly without affecting the quality, you need to have an Image pixel size of:

30 * UIScreen.main.scale = 60 pixels (if 2X scale)

or

30 * UIScreen.main.scale = 90 pixels (if 3x scales)

This is also the same reason why you need to provide iOS with @2x and @3x scaled images.

So if you want to resize your UIImage to a smaller size you need to take scaling into consideration. Otherwise your Images will be scaled to fill out your UIImageView and they will become blurry because the UIImageView is bigger than the UIImage size.

A good way to see this is if you set your yourImageView.contentMode = .Center you will notice the UIImage is smaller than the UIImageView itself.

I don't code in Swift, so I cant provide you with direct code ( to tired to translate) but if you look at other threads:

scale image to smaller size in swift3

You see that your UIGraphicsBeginImageContext is for example missing the scale input.

scale

The scale factor to apply to the bitmap. If you specify a value of 0.0, the scale factor is set to the scale factor of the device’s main screen.

Edit: In your case, something like this:

newWidth = newWidth / UIScreen.main.scale

UIGraphicsBeginImageContextWithOptions(CGSize(width: newWidth, height: newWidth), true, 0)
  • Thanks for the answer but i have used tabbar item which by default manage its imageView. I dont have the access to it hence cant fiddle around with the imageView's content mode. Moreover when i am scaling image as suggested by you i get an image of size 90x90 bloating out of the bottom bar. – Ishika Aug 28 '17 at 06:02
  • @Ishika You are doing the calculations wrong If it is moving out of the tabbar imageView. If you apply a scale factor of 0.0 , and type 30x30, you will have 60x60 pixels and 90x90 on 3x scale. If you type 90x90 , you will end up with 180x180 pixels or 270x270 pixels . You need to scale it down the other way around, so you end up with 30 pixels, not 30 points. See my edited answer. You can still see the pixel size of the image with this https://developer.apple.com/documentation/coregraphics/1456148-cgimagegetwidth –  Aug 28 '17 at 08:04