Визуализация UILabel для UIImage в гораздо более высоком разрешении - PullRequest
1 голос
/ 14 апреля 2020

Я использую приведенную ниже функцию для рендеринга 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, но это ничего не делает.

1 Ответ

2 голосов
/ 14 апреля 2020

Вам потребуется масштабировать рамку и размер шрифта надписи перед тем, как рисовать ее в новом контексте изображения:

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)

enter image description here

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...