19

我想渲染到屏幕外位图(或 RGBA 值数组),然后UIView在视图drawRect函数中将这些位图 blit 到 a during 。我更愿意进行完整的 32 位渲染(包括 alpha 通道),但也对 24 位渲染感到满意。

有人介意用一些代码片段或相关 API 为我指明正确的方向吗?

此外,我确切地知道如何使用 OpenGL 来完成这项工作——我更愿意在 Core Graphics 本身中完成这项工作。

4

4 回答 4

15

要渲染到屏幕外上下文并将其保存为 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。

于 2009-12-26T09:17:49.257 回答
3

您可以使用CGBitmapContext。您可以从 CGBitmapContext 生成图像并在 drawRect 期间绘制它。

于 2009-01-04T04:41:39.263 回答
2

如果您不需要位图上下文而只CGDataProviderCreateWithData需要.CGImageCreateCGImageRef

于 2009-03-18T07:53:40.300 回答
1

为了将来参考,这里是 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)
    }

}
于 2016-08-24T09:19:11.423 回答