Как визуализировать растровое изображение за пределами экрана, а затем вывести его на экран с помощью Core Graphics

Я хотел бы отобразить внеэкранное растровое изображение (или массив значений RGBA), а затем преобразовать их в UIView во время функции представления drawRect. Я бы предпочел полный 32-битный рендеринг (включая альфа-канал), но также удовлетворился бы 24-битным рендерингом.

Не мог бы кто-нибудь указать мне правильное направление с некоторыми фрагментами кода или соответствующими API?

Кроме того, я точно знаю, как это сделать с помощью OpenGL — я просто предпочитаю выполнять эту работу в самом Core Graphics.


person Frank Krueger    schedule 04.01.2009    source источник
comment
Какая-то конкретная причина? Если вы собираетесь повторно использовать изображение, вы можете создать его на своем Mac и сохранить в виде файла PNG для копирования в пакет. Если вы не храните его, вероятно, будет быстрее просто рисовать прямо в drawRect:. (И помните: профилируйте, а затем оптимизируйте!)   -  person Peter Hosey    schedule 18.03.2009


Ответы (4)


Чтобы выполнить рендеринг во внеэкранный контекст и сохранить его как CGImageRef:

void *bitmapData = calloc(height, bytesPerLine);
CGContextRef offscreen = CGBitmapContextCreate(..., bitmapData, ...)
// draw stuff into offscreen
CGImageRef image = CGBitmapContextCreateImage(offscreen);
CFRelease(offscreen);
free(bitmapData);

Чтобы нарисовать его на экране:

- (void)drawRect:(CGRect)rect {
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextDrawImage(context, rect, image);
}

Вы также можете просто сохранить изображение в свойстве содержимого слоя представления (view.layer.contents = image) или использовать UIImageView.

person benzado    schedule 26.12.2009

Вы можете использовать CGBitmapContext. Вы можете сгенерировать изображение из CGBitmapContext и нарисовать его во время drawRect.

person phi    schedule 04.01.2009

Используйте CGDataProviderCreateWithData и CGImageCreate, если вам не нужен растровый контекст и вам нужен только CGImageRef.

person Community    schedule 18.03.2009

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

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

Контроллер представления:

import UIKit

class ViewController: UIViewController {
    @IBOutlet var myView: MyView!
    var bitmapContext: CGContext?

    override func viewDidLoad() {
        super.viewDidLoad()
        createBitmapContext()
        drawContentIntoBitmap()
        myView.update(from: bitmapContext)
        releaseBitmapContext()
    }

    func createBitmapContext() {
        bitmapContext = CGBitmapContextCreate(
            nil,                                                        // auto-assign memory for the bitmap
            Int (myView.bounds.width * UIScreen.mainScreen().scale),    // width of the view in pixels
            Int (myView.bounds.height * UIScreen.mainScreen().scale),   // height of the view in pixels
            8,                                                          // 8 bits per colour component
            0,                                                          // auto-calculate bytes per row
            CGColorSpaceCreateDeviceRGB(),                              // create a suitable colour space
            CGImageAlphaInfo.PremultipliedFirst.rawValue)               // use quartz-friendly byte ordering
    }

    func drawContentIntoBitmap() {
        CGContextScaleCTM(bitmapContext, UIScreen.mainScreen().scale, UIScreen.mainScreen().scale)  // convert to points dimensions
        CGContextSetStrokeColorWithColor (bitmapContext, UIColor.redColor().CGColor)
        CGContextSetLineWidth (bitmapContext, 5.0)
        CGContextStrokeEllipseInRect (bitmapContext, CGRectMake(50, 50, 100, 100))
    }

    func releaseBitmapContext() {
        bitmapContext = nil // in Swift, CGContext and CGColorSpace objects are memory managed by automatic reference counting
    }
}

Подкласс UIView:

import UIKit

class MyView: UIView {     
    var cgImage: CGImage?

    func update(from bitmapContext: CGContext?) {
        cgImage = CGBitmapContextCreateImage(bitmapContext)
        setNeedsDisplay()
    }

    override func drawRect(rect: CGRect) {
        let displayContext = UIGraphicsGetCurrentContext()
        CGContextDrawImage(displayContext, bounds, cgImage)
    }

}
person Martin CR    schedule 24.08.2016