Cómo representar un mapa de bits fuera de la pantalla y luego pasar a la pantalla con Core Graphics

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

Pregunta

Me gustaría renderizar a un mapa de bits fuera de pantalla (o una matriz de valores RGBA) y luego combinarlos en una UIView durante la función drawRect de la vista. Preferiría realizar la representación completa de 32 bits (incluido el canal alfa), pero también estaría contento con la representación de 24 bits.

¿A alguien le importaría apuntarme en la dirección correcta con algunos fragmentos de código o API relevantes?

Además, sé exactamente cómo hacerlo utilizando OpenGL. Preferiría hacer este trabajo en Core Graphics.

¿Fue útil?

Solución

Para renderizar en un contexto fuera de la pantalla y guardarlo como CGImageRef:

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

Para dibujarlo en la pantalla:

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

También puede simplemente guardar la imagen en la propiedad de contenido de la capa de la vista ( view.layer.contents = image ), o usar un UIImageView.

Otros consejos

Puede usar un CGBitmapContext . Puede generar una imagen desde un CGBitmapContext y dibujarla durante su drawRect.

Use CGDataProviderCreateWithData y CGImageCreate si no necesita el contexto de mapa de bits y solo quiere el CGImageRef .

Para referencias futuras, aquí hay un ejemplo completo en Swift 2.1 de renderizar a un mapa de bits fuera de la pantalla y mostrarlo en la pantalla.

Tenga en cuenta que una vez que haya creado el contexto de mapa de bits, puede seguir dibujando más contenido en él y actualizar la vista cuando lo desee. Esto es excelente si desea realizar una larga operación de dibujo en un hilo de fondo y mostrar periódicamente el progreso al usuario.

Ver controlador:

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

Subclase 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 bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top