How to increase quality of rendered image for UIImageView?

605 views Asked by At

I have an UIImageView with contentMode = .aspectFit. I have an image in imageView, which dimension is bigger than size of imageView. User can draw some lines and save them as sublayer. After that I need to save the edited image. But quality of saved image is worse than quality of image which I load. What am I doing wrong? I tried to use transform, but it didn't work.

import UIKit

extension UIImageView {
    
    var contentClippingRect: CGRect {
        let imgViewSize = self.frame.size
        let imgSize = self.image?.size ?? .zero
        let scaleW = imgViewSize.width / imgSize.width
        let scaleH = imgViewSize.height / imgSize.height
        let aspect = fmin(scaleW, scaleH)
        
        let width = imgSize.width * aspect
        let height = imgSize.height * aspect
        
        let imageRect = CGRect(x: (imgViewSize.width-width)/2 + self.frame.origin.x, y: (imgViewSize.height-height)/2 + self.frame.origin.y, width: width, height: height)
        return imageRect
    }
    
    func asImage() -> UIImage {
        let imageRect = self.contentClippingRect
        let renderer = UIGraphicsImageRenderer(bounds: imageRect)
        let renderedImage = renderer.image { rendererContext in
            layer.render(in: rendererContext.cgContext)
        }

        return renderedImage
    }
}
1

There are 1 answers

0
someone On

You can use UIGraphicsImageRendererFormat().scale it will increase quality of the rendered image a bit.

import UIKit

extension UIImageView {

var contentClippingRect: CGRect {
    let imgViewSize = self.frame.size
    let imgSize = self.image?.size ?? .zero
    let scaleW = imgViewSize.width / imgSize.width
    let scaleH = imgViewSize.height / imgSize.height
    let aspect = fmin(scaleW, scaleH)
    
    let width = imgSize.width * aspect
    let height = imgSize.height * aspect
    
    let imageRect = CGRect(x: (imgViewSize.width-width)/2 + self.frame.origin.x, y: (imgViewSize.height-height)/2 + self.frame.origin.y, width: width, height: height)
    return imageRect
}

func asImage() -> UIImage {
    let imageRect = self.contentClippingRect
    
    //add this
    let format = UIGraphicsImageRendererFormat()
    format.scale = 2

    let renderer = UIGraphicsImageRenderer(bounds: imageRect, format: format)
    let renderedImage = renderer.image { rendererContext in
        layer.render(in: rendererContext.cgContext)
    }

    return renderedImage
}
}