首页 > 解决方案 > 以更高的分辨率将 UILabel 渲染到 UIImage

问题描述

我正在使用以下函数将 UILabel 呈现给 UIImage

func labelToImage(_ label: UILabel) -> UIImage {           
    UIGraphicsBeginImageContextWithOptions(CGSize(width: label.frame.size.width*10, height: label.frame.size.height*10), false, 0)
    guard let context = UIGraphicsGetCurrentContext() else { return UIImage() }
    defer { UIGraphicsEndImageContext() }
    label.layer.render(in: context)
    return UIGraphicsGetImageFromCurrentImageContext() ?? UIImage()
}

但是生成的图像的分辨率对于我的需要来说太低了,我需要它大约 10 倍。我不想缩放生成的图像,因为这会使它像素化。

我想缩放 UILabel 然后将其渲染为图像。我已经尝试过CGAffinTransform Scale,但这并没有做任何事情。

标签: iosswiftuikit

解决方案


在将标签绘制到新的图像上下文之前,您需要缩放标签的框架和字体大小:

func labelToImage(_ label: UILabel) -> UIImage? {
    let size = label.frame.size.applying(.init(scaleX: 10, y: 10))
    UIGraphicsBeginImageContextWithOptions(size, false, 0)
    label.frame.size = size
    label.font = label.font.withSize(label.font.pointSize * 10)
    defer { UIGraphicsEndImageContext() }
    label.draw(.init(origin: .zero, size: size))
    return UIGraphicsGetImageFromCurrentImageContext()
}

您还可以扩展 UILabel 以将其缩放到特定大小或百分比:

extension UILabel {
    func scaledImage(to size: CGSize) -> UIImage {
        let format = UIGraphicsImageRendererFormat()
        format.opaque = false
        let aspectRatio = size.width/frame.size.width
        frame = frame.applying(.init(scaleX: aspectRatio, y: aspectRatio))
        font = font.withSize(font.pointSize * aspectRatio)
        return UIGraphicsImageRenderer(size: size, format: format).image { _ in
            draw(.init(origin: .zero, size: size))
        }
    }
    func scaledImage(by percentage: CGFloat) -> UIImage {
        let format = UIGraphicsImageRendererFormat()
        format.opaque = false
        frame = frame.applying(.init(scaleX: percentage, y: percentage))
        font = font.withSize(font.pointSize * percentage)
        return UIGraphicsImageRenderer(size: frame.size, format: format).image { _ in
            draw(.init(origin: .zero, size: frame.size))
        }
    }
}

游乐场测试:

let label = UILabel(frame: .init(origin: .zero, size: .init(width: 200, height: 30)))
label.text = "StackOverflow"
label.scaledImage(by: 10)

在此处输入图像描述


推荐阅读