오프 스크린 비트 맵으로 렌더링하는 방법 코어 그래픽을 사용하여 스크린에 블리트
-
03-07-2019 - |
문제
오프 스크린 비트 맵 (또는 RGBA 값 배열)으로 렌더링 한 다음 그를 UIView
보기 중 drawRect
기능. 나는 전체 32 비트 렌더링 (알파 채널 포함)을 선호하지만 24 비트 렌더링에 만족할 것입니다.
코드 스 니펫이나 관련 API로 올바른 방향으로 나를 지적하는 사람이 있습니까?
또한 OpenGL을 사용 하여이 작업을 수행하는 방법을 정확히 알고 있습니다. 핵심 그래픽 자체 에서이 작업을 수행하는 것이 좋습니다.
해결책
오프 스크린 컨텍스트로 렌더링하고 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를 사용하십시오.
다른 팁
당신은 a를 사용할 수 있습니다 cgbitmapcontext. cgbitmapcontext에서 이미지를 생성하고 DrawRect 중에 그릴 수 있습니다.
사용 CGDataProviderCreateWithData
그리고 CGImageCreate
비트 맵 컨텍스트가 필요하지 않고 CGImageRef
.
향후 참조를 위해 다음은 오프 스크린 비트 맵으로 렌더링하고 화면에 표시하는 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)
}
}