【问题标题】:How to render to offscreen bitmap then blit to screen using Core Graphics如何使用 Core Graphics 渲染到屏幕外位图然后 blit 到屏幕
【发布时间】:2010-09-29 10:43:24
【问题描述】:

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

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

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

【问题讨论】:

  • 有什么特别的原因吗?如果您要重复使用该图像,您可能会考虑在您的 Mac 上生成它并将其保存为 PNG 文件以复制到包中。如果您不保留它,那么在 drawRect: 中直接绘制可能会更快。 (记住:配置文件,然后优化!)

标签: iphone bitmap core-graphics bitblit


【解决方案1】:

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

【讨论】:

    【解决方案2】:

    如果您不需要位图上下文而只需要CGImageRef,请使用CGDataProviderCreateWithData 和CGImageCreate。

    【讨论】:

      【解决方案3】:

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

      【讨论】:

        【解决方案4】:

        为了将来参考,这里有一个在 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)
            }
        
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2011-08-10
          • 1970-01-01
          • 1970-01-01
          • 2010-12-25
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多