SwiftUI - при сохранении изображения на общий лист изображение остается размытым / с низким разрешением

В моем приложении есть небольшой код, который генерирует QR-код и масштабирует его (ссылка на код, которую я использовал из эта ссылка из Hackng with Swift. Теперь я использую общий лист, чтобы позволить пользователю сохранить qr-код в своей фотопленке и , он работает, но сохраняет изображение в низком разрешении, и оно сохраняется в фотопленке размытым (и я предполагаю, что если оно будет передано другими методами, оно также будет размытым)

Вот код моей функции общего листа:

struct ActivityView: UIViewControllerRepresentable {

    let activityItems: [Any]
    let applicationActivities: [UIActivity]?

    func makeUIViewController(context: UIViewControllerRepresentableContext<ActivityView>) -> UIActivityViewController {
        return UIActivityViewController(activityItems: activityItems, applicationActivities: applicationActivities)
    }

    func updateUIViewController(_ uiViewController: UIActivityViewController, context: UIViewControllerRepresentableContext<ActivityView>) {

    }
}

и вот код в моей структуре представления:

.sheet(isPresented: $showShareSheet) {
                    ShareSheet(activityItems: [self.qrCodeImage])
                }

Есть ли уловка для удаления интерполяции на изображении, когда оно сохраняется на общем листе, например .interpolation (.none) в самом представлении изображения?


person Benjamin B.    schedule 21.07.2020    source источник
comment
Если вы распечатаете размеры изображения, сгенерированные в вашем приложении, какой ответ вы получите?   -  person Samuel-IH    schedule 22.07.2020


Ответы (1)


Ваша проблема в том, что изображение QR-кода на самом деле крошечное! Как действительно крошечный:

Printing description of image:
<UIImage:0x60000202cc60 anonymous {23, 23}>

Когда вы делитесь этим изображением, способ его отображения зависит от программы или приложения, которое будет отображать его, и, насколько мне известно, не контролируется вашим приложением.


Тем не мение,

есть способ сделать его красивым в других приложениях, например, увеличить разрешение до большего значения, чтобы при рендеринге казалось, что пиксели будут четкими.

Как бы этого добиться? Я думаю, что у меня есть пример, похороненный где-то в старом коде, я покопаюсь в нем и посмотрю, смогу ли я найти вам пример;)

Редактировать

Я нашел код:

extension UIImage {
    func resized(toWidth width: CGFloat) -> UIImage? {
        let canvasSize = CGSize(width: round(width), height: CGFloat(ceil(width/size.width * size.height)))
        UIGraphicsBeginImageContextWithOptions(canvasSize, false, scale)
        defer { UIGraphicsEndImageContext() }
        let context = UIGraphicsGetCurrentContext();
        context?.interpolationQuality = .none
        // Set the quality level to use when rescaling
        draw(in: CGRect(origin: .zero, size: canvasSize))
        let r = UIGraphicsGetImageFromCurrentImageContext()
        return r
    }
}

Хитрость заключается в том, чтобы обеспечить способ масштабирования изображения, но настоящая магия находится в строке 7:

context?.interpolationQuality = .none

Если вы исключите эту строку, вы получите размытые изображения, что и делает ОС по умолчанию, потому что вы, как правило, не хотите видеть края пикселей в изображениях.

Вы можете использовать это расширение так:

.sheet(isPresented: $showShareSheet) {
    ShareSheet(activityItems: [self.qrCodeImage.resized(toWidth: 512) ?? UIImage()])
}

Однако при этом размер изображения может изменяться чаще, чем необходимо. Оптимально изменить его размер с помощью той же функции, в которой вы его генерируете.

person Samuel-IH    schedule 21.07.2020