Pergunta

Eu gostaria de renderizar um bitmap fora da tela (ou matriz de valores de RGBA) e depois prendê -los a um UIView Durante o View's drawRect função. Eu preferiria fazer uma renderização completa de 32 bits (incluindo o canal alfa), mas também se contentaria com a renderização de 24 bits.

Alguém se importaria de me apoiar na direção certa com alguns trechos de código ou APIs relevantes?

Além disso, eu sei exatamente como fazer isso usando o OpenGL - eu preferiria fazer esse trabalho nos próprios gráficos principais.

Foi útil?

Solução

Para renderizar um contexto fora da tela e salvá -lo como um CGIMAGEREF:

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

Para desenhá -lo na tela:

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

Você também pode apenas salvar a imagem na propriedade de conteúdo da camada da vista (view.layer.contents = image), ou use um UIImageView.

Outras dicas

Você pode usar um CGBITMAPCONTEXT. Você pode gerar uma imagem a partir de um cgbitmapContext e desenhá -la durante o seu drawrect.

Usar CGDataProviderCreateWithData e CGImageCreate Se você não precisa do contexto de bitmap e só deseja o CGImageRef.

Para referência futura, aqui está um exemplo completo no Swift 2.1 de renderização para um bitmap fora da tela e exibi -lo na tela.

Observe que, depois de criar o contexto do bitmap, você pode continuar desenhando mais conteúdo e atualizando a visualização quando quiser. Isso é ótimo se você deseja fazer uma longa operação de desenho em um encadeamento de segundo plano e mostrar periodicamente o progresso para o usuário.

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

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

}
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top