我想渲染到屏幕外的位图(或RGBA值数组),然后在视图的UIView
函数中将它们渲染到drawRect
。我更喜欢做完整的32位渲染(包括alpha通道),但也会满足于24位渲染。
有人会介意用一些代码片段或相关的API指出我正确的方向吗?
另外,我确切知道如何使用OpenGL完成此操作 - 我更愿意在Core Graphics本身中完成这项工作。
答案 0 :(得分: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。
答案 1 :(得分:3)
您可以使用CGBitmapContext。您可以从CGBitmapContext生成图像并在drawRect中绘制它。
答案 2 :(得分:2)
如果您不需要位图上下文而只需要CGDataProviderCreateWithData
,请使用CGImageCreate
和CGImageRef
。
答案 3 :(得分: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)
}
}