オフスクリーンビットマップにレンダリングし、Core Graphicsを使用してスクリーンにブリットする方法

StackOverflow https://stackoverflow.com/questions/410313

質問

オフスクリーンビットマップ(またはRGBA値の配列)にレンダリングし、ビューの drawRect 関数でそれらを UIView にblitします。完全な32ビットレンダリング(アルファチャネルを含む)を行うことを希望しますが、24ビットレンダリングを使用したコンテンツにもなります。

コードスニペットまたは関連するAPIを使用して正しい方向に向けてくれる人はいませんか?

また、OpenGLを使用してこれを行う方法を正確に知っています。CoreGraphics自体でこの作業を行うことをお勧めします。

役に立ちましたか?

解決

オフスクリーンコンテキストにレンダリングして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を使用することもできます。

他のヒント

CGBitmapContext を使用できます。 CGBitmapContextから画像を生成し、drawRectで描画できます。

ビットマップコンテキストが不要で CGImageRef のみが必要な場合は、 CGDataProviderCreateWithData および CGImageCreate を使用します。

今後の参考のために、オフスクリーンビットマップにレンダリングして画面に表示するSwift 2.1の完全な例を示します。

ビットマップコンテキストを作成したら、さらに多くのコンテンツを描画して、必要に応じてビューを更新できることに注意してください。これは、バックグラウンドスレッドで長時間の描画操作を行い、定期的にユーザーに進行状況を表示する場合に便利です。

View Controller:

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)
    }

}
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top