Почему в некоторых случаях снимок представления может выглядеть вдвое большим? - PullRequest
0 голосов
/ 28 марта 2019

ПРОБЛЕМА

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

Подробностив выпуске

я делаю снимки размером 2 UIViews, которые мы можем вызвать viewA и viewB следующим образом.

  • viewA :представление добавляется в иерархию представлений при создании снимка.

  • viewB : Полностью определено, но еще не добавлено виерархия представления при создании снимка.Снимок затем обрезается x количество раз, и результат добавляется к некоторому значению UIView для отображения.

Я протестировал 3 различных кода, чтобы получить результат, который я ищу: одинобеспечивает желаемый снимок изображения, но с низким качеством рендеринга;два других обеспечивают более высокое качество рендеринга изображения и правильный результат для viewA , но для viewB , хотя снимок, кажется, имеет правый прямоугольник (я проверил rects), показанные изображения появляютсяслишком большой (как если бы они были увеличены в два раза).

CODE

  1. Extension # 1 : обеспечивает правильные результаты, но с низким качеством изображения

    extension UIView {
    
        func takeSnapshot() -> UIImage? {
            UIGraphicsBeginImageContext(self.frame.size)
            self.layer.render(in: UIGraphicsGetCurrentContext()!)
            let snapshot = UIGraphicsGetImageFromCurrentImageContext()
            UIGraphicsEndImageContext()
    
            return snapshot
        }
    }
    
  2. Extension # 2 : обеспечивает правильное качество изображения, но обрезанные изображения viewB отображаются в два раза больше

    extension UIView {
        func snapshot(of rect: CGRect? = nil, afterScreenUpdates: Bool = true) -> UIImage {
            return UIGraphicsImageRenderer(bounds: rect ?? bounds).image { _ in
                drawHierarchy(in: bounds, afterScreenUpdates: true)
            }
        }
    }
    
  3. Extension # 3 : Аналогично, обеспечивает правильное качество изображения, но обрезанные изображения viewB отображаются в два раза больше

    extension UIView {
        func takeScreenshot() -> UIImage {
            UIGraphicsBeginImageContextWithOptions(self.bounds.size, false, UIScreen.main.scale)
    
            drawHierarchy(in: self.bounds, afterScreenUpdates: true)
            let image = UIGraphicsGetImageFromCurrentImageContext()
            UIGraphicsEndImageContext()
    
            if (image != nil) { return image! }
            return UIImage()
        }
    }
    

Последнее, но непо крайней мере, (упрощенный) код для извлечения обрезанных изображений из снимка

    for i in (0...numberOfCroppedImages) {
        let rect    = CGRect(x: CGFloat(i) * snapshot!.size.width / CGFloat(numberOfCroppedImages), y: 0, width: snapshot!.size.width / CGFloat(numberOfCroppedImages), height:snapshot!.size.height)

        // defines the container view for the fragmented snapshots
        let view    = UIView()
        view.frame  = rect


        // defines the layer with the fragment of the snapshot
        let layer           = CALayer()
        layer.frame.size    = rect.size
        let img             = snapshot?.cgImage?.cropping(to: rect)
        layer.contents      = img
        view.layer.addSublayer(layer)
    }

Пока предпринятые действия

Я дважды проверил все CGRect, и я не нашел никаких проблемс ними: вид прямоугольников, а также размеры снимка смм, ожидаемый, но у меня все еще остаются слишком большие отрендеренные изображения с расширениями # 2 и # 3 для viewB (viewA правильно визуализируется), в то время как расширение # 1 дает изображения правильных размеров, но сслишком низкое качество для адекватного использования.

Может ли быть проблема с drawInHierarchy(in: afterScreenUpdates:)?или, в качестве альтернативы, преобразование в cgImage с let img = snapshot?.cgImage?.cropping(to: rect)?

Я был бы очень благодарен за любые указатели!

1 Ответ

0 голосов
/ 28 марта 2019

Я публикую решение, которое мне удалось найти:

Во-первых, расширение снимка, которое отображает (для моего случая) ожидаемые результаты (с точки зрения качества и размера) независимо от того, добавлено ли представление в иерархию или нет, обрезано или нет:

    extension UIView {

        func takeSnapshot(of rect: CGRect? = nil, afterScreenUpdates: Bool = true) -> UIImage {
            return UIGraphicsImageRenderer(bounds: rect ?? bounds).image { (context) in
                self.layer.render(in: context.cgContext)
            }
        }

    }

Затем обновленная версия кода, который делает снимок прямоугольника в представлении:

    let view    = UIView()
    view.frame  = rect
    let img = self.takeSnapshot(of: rect, afterScreenUpdates: true).cgImage
    view.layer.contents = img

Различие состоит в том, что вместо снимка всего снимка делается снимок прямоугольника на виде.

Надеюсь, это поможет.

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