Quartz2D, как сохранить текущий контекст, а затем рисовать поверх него?

Я пытаюсь рисовать с помощью Quartz2D, но я обнаружил, что рисунок сильно отстает сразу после нескольких точек. Поэтому мне интересно, как я могу кэшировать текущий контекст в bmp, jpg или слой, а затем снова рисовать на слое, чтобы сделать рисунок более плавным. Каким способом лучше всего это сделать? Спасибо!


person gtr32x    schedule 26.01.2011    source источник


Ответы (3)


IIRC, Quartz2D использует модель рисования для рендеринга контента, и как только вы рисуете что-то, вы вообще не можете с ним взаимодействовать, поэтому я не понимаю, почему кэширование текущего контекста может помочь.

Однако, если вы хотите кэшировать текущий контекст, код выглядит примерно так:

// Begin image context
UIGraphicsBeginImageContext(view.bounds.size);

[view.layer renderInContext:UIGraphicsGetCurrentContext()];
CGImageRef screenshotRef = CGBitmapContextCreateImage(UIGraphicsGetCurrentContext());
UIImage *screenshot = [[UIImage alloc] initWithCGImage:screenshotRef];

// End image context
UIGraphicsEndImageContext();
// Release CGImage
CGImageRelease(screenshotRef);

return screenshot;
person johnw188    schedule 26.01.2011
comment
Да, я хочу сделать это, используя модель для рисования. Однако моя текущая реализация сохраняет все предыдущие точки касания в массив и перерисовывает их каждый кадр. Следовательно, он быстро накапливается и сильно отстает от программы. Этот код используется внутри контроллера представления? Я хочу что-то, что я могу использовать и сохранять внутри функции drawRect. Не знаю, может я не правильно мыслю? Спасибо за ответ! - person gtr32x; 27.01.2011
comment
Вы не хотите сохранять текущий рисунок внутри функции drawRect. Очистка графического конвейера может быть очень медленной. - person hotpaw2; 27.01.2011

Вместо того, чтобы рисовать в drawRect UIView и пытаться сохранить этот слой рисования, вы можете попытаться нарисовать растровое изображение в фоновом потоке. Вам никогда не придется очищать растровое изображение, и вы можете просто продолжать рисовать в нем. Тогда все, что вам нужно сделать в UIView drawRect, — это отрисовать одно изображение последнего доступного растрового изображения, что iOS может сделать довольно быстро.

person hotpaw2    schedule 27.01.2011

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

    //Draw path and return Image
    let firstBeizerPath:UIImage = drawPath(firstBeizerpath: drawCircle())
    let secondBeizerPath:UIImage = drawPath(firstBeizerpath: polygon())

    //Draw different saved context into single image.
    let image = UIImage(). drawOneLayerOverAnother(firstImage:firstBeizerPath , secondImage:secondBeizerPath)

extension UIImage {
    func drawOneLayerOverAnother(firstImage:UIImage , secondImage:UIImage ) -> UIImage {
    UIGraphicsBeginImageContext(firstLayer.size)

    firstImage.draw(in: CGRect(x: 0, y: 0, width: firstLayer.size.width, height: firstLayer.size.height) )
    secondImage.draw(in: CGRect(x: 0, y: 0, width: firstLayer.size.width, height: firstLayer.size.height) )

    let newImage = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()
    return newImage!
    }
}

Демонстрационное приложение

person Shrawan    schedule 16.12.2016