iphone - presentacion - Cómo renderizar en mapa de bits fuera de la pantalla luego blit a la pantalla usando Core Graphics
nuevo iphone se 2018 (4)
Me gustaría renderizar a un mapa de bits fuera de pantalla (o matriz de valores RGBA) y luego UIView
a un UIView
durante la función drawRect
la vista. Preferiría hacer una representación completa de 32 bits (incluido el canal alfa), pero también estaría satisfecho con la representación de 24 bits.
¿Alguien me importaría señalarme en la dirección correcta con algunos fragmentos de código o API relevantes?
Además, sé exactamente cómo hacer esto con OpenGL. Preferiría hacer este trabajo en Core Graphics.
Puede usar un CGBitmapContext . Puede generar una imagen desde CGBitmapContext y dibujarla durante su drawRect.
Utilice CGDataProviderCreateWithData y CGImageCreate si no necesita el contexto de mapa de bits y solo desea el CGImageRef.
Para representar en un contexto fuera de pantalla y guardarlo como un 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 guardar la imagen en la propiedad de contenido de la capa de la vista ( view.layer.contents = image
), o usar un UIImageView.
Para referencia futura, aquí hay un ejemplo completo en Swift 2.1 de renderizado a un mapa de bits fuera de pantalla y mostrándolo 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 actualizando la vista cuando lo desee. Esto es excelente si desea realizar una operación de dibujo larga en una secuencia de fondo y mostrar periódicamente el progreso al usuario.
Controlador de vista:
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)
}
}