How to enlarge a tiny text image without loosing quality?

房东的猫 提交于 2020-12-26 05:04:27

问题


The text image is very tiny, 17px x 10px in size

It can be enlarge perfectly in MacOS

let width  = scale * image.size.width * kScale
        let height = scale * image.size.height * kScale
        super.init(frame: NSRect(x: 0, y: 0, width: width, height: height))
        self.makeConstraints(width: width, height: height)
        self.drawBlock = { (context, bounds) in
            image.draw(in: bounds)
        }

and redraw it:

   override func draw(_ dirtyRect: NSRect) {
        // Fill with optional background color.

        if let color = bgColor {
            color.set()
            bounds.fill(using: .sourceOver)
        }

        // Draw with optional draw block.

        if let block = drawBlock {
            let context = NSGraphicsContext.current!.cgContext
            block(context, bounds)
        }

        super.draw(dirtyRect)
    }

I tried to the same thing in iOS with the following two methods, I got an image with low quality:

   func imageScaledToSize(image: UIImage, size : CGSize) -> UIImage{
        UIGraphicsBeginImageContextWithOptions(size, false, 0.0)

        let imageRect = CGRect(origin: .zero, size: size)
        image.draw(in: imageRect)

        let scaledImage = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()

        return scaledImage!
    }

   func resizeImage(image: UIImage, newSize: CGSize) -> (UIImage) {

       let newRect = CGRect(x: 0, y: 0, width: newSize.width, height: newSize.height).integral
       UIGraphicsBeginImageContextWithOptions(newSize, false, 0)
       let context = UIGraphicsGetCurrentContext()

       // Set the quality level to use when rescaling
        context!.interpolationQuality = CGInterpolationQuality.high
       let flipVertical = CGAffineTransform(a: 1, b: 0, c: 0, d: -1, tx: 0, ty: newSize.height)

       context!.concatenate(flipVertical)
       // Draw into the context; this scales the image
       context?.draw(image.cgImage!, in: CGRect(x: 0.0,y: 0.0, width: newRect.width, height: newRect.height))

       let newImageRef = context!.makeImage()! as CGImage
       let newImage = UIImage(cgImage: newImageRef)

       // Get the resized image from the context and a UIImage
       UIGraphicsEndImageContext()

       return newImage
    }

How to get a better image when resize it? Thanks.


回答1:


You need to set your context interpolation to none before drawing to your context:

extension UIImage {
    func resized(toWidth width: CGFloat, interpolationQuality: CGInterpolationQuality = .none) -> UIImage? {
        let canvasSize = CGSize(width: width, height: CGFloat(ceil(width/size.width * size.height)))
        UIGraphicsBeginImageContextWithOptions(canvasSize, false, scale)
        defer { UIGraphicsEndImageContext() }
        guard let context = UIGraphicsGetCurrentContext() else { return nil }
        context.interpolationQuality = interpolationQuality
        draw(in: CGRect(origin: .zero, size: canvasSize))
        return UIGraphicsGetImageFromCurrentImageContext()
    }
}

For iOS 10 or later you can use UIGraphicsImageRenderer as follow:

extension UIImage {
    func resized(toWidth width: CGFloat, interpolationQuality: CGInterpolationQuality = .none, isOpaque: Bool = false) -> UIImage? {
        let canvas = CGSize(width: width, height: CGFloat(ceil(width/size.width * size.height)))
        let format = imageRendererFormat
        format.opaque = isOpaque
        return UIGraphicsImageRenderer(size: canvas, format: format).image { context in
            context.cgContext.interpolationQuality = interpolationQuality
            draw(in: CGRect(origin: .zero, size: canvas))
        }
    }
}


来源:https://stackoverflow.com/questions/59692077/how-to-enlarge-a-tiny-text-image-without-loosing-quality

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!