layers: [CGImageRef]
의 일부를 내 맞춤 NSView
의 drawLayer(thisLayer: CALayer!, inContext ctx: CGContext!)
루틴에 알파 혼합하려고합니다. 지금까지 나는 그 레이어를 drawLayer 컨텍스트에 그리는 데 CGContextDrawImage()
을 사용했습니다. 프로파일 링 중에 CGContextDrawImage()
은 CPU 시간의 70 %를 필요로하므로 Accelerate 프레임 워크를 사용해보기로 결정했습니다. 코드를 변경했지만 충돌이 발생하고 이유가 무엇인지 알 수 없습니다.vImageAlphaBlend가 충돌 함
나는 이런 식으로 그 레이어를 만드는거야 :이 같은
func addLayer() {
let colorSpace: CGColorSpaceRef = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB)
let bitmapInfo = CGBitmapInfo(CGImageAlphaInfo.PremultipliedFirst.rawValue)
var layerContext = CGBitmapContextCreate(nil, UInt(canvasSize.width), UInt(canvasSize.height), 8, UInt(canvasSize.width * 4), colorSpace, bitmapInfo)
var newLayer = CGBitmapContextCreateImage(layerContext)
layers.append(newLayer)
}
내 drawLayers 일상적인 외모 :
override func drawLayer(thisLayer: CALayer!, inContext ctx: CGContext!)
{
var ctxImageBuffer = vImage_Buffer(data:CGBitmapContextGetData(ctx),
height:CGBitmapContextGetHeight(ctx),
width:CGBitmapContextGetWidth(ctx),
rowBytes:CGBitmapContextGetBytesPerRow(ctx))
for imageLayer in layers
{
//CGContextDrawImage(ctx, CGRect(origin: frameOffset, size: canvasSize), imageLayer)
var inProvider:CGDataProviderRef = CGImageGetDataProvider(imageLayer)
var inBitmapData:CFDataRef = CGDataProviderCopyData(inProvider)
var buffer:vImage_Buffer = vImage_Buffer(data: &inBitmapData, height:
CGImageGetHeight(imageLayer), width: CGImageGetWidth(imageLayer), rowBytes:
CGImageGetBytesPerRow(imageLayer))
vImageAlphaBlend_ARGB8888(&buffer, &ctxImageBuffer, &ctxImageBuffer, 0)
}
}
canvasSize가에 allways 동일하며 모든 레이어가 같은 크기를 가지고, 그래서 나는 왜 마지막 줄이 망가 졌는지 이해하지 못한다.
또한 CGLayerRefs에서 직접 vImageBuffers를 만드는 새로운 편리한 함수를 사용하는 방법을 알지 못합니다. 그것이 내가 복잡한 방식으로하는 이유입니다.
도움을 주시면 감사하겠습니다.
편집
inBitmapData
실제로 내가 설정 한 배경 색상을 반영 픽셀 데이터를 보유하고 있습니다. 그러나 디버거 po &inBitmapData
을 할 수 없습니다이 메시지와 함께 실패합니다
그래서 내가 inBitmapData에 대한 포인터를 얻을 수있는 방법을 찾았다. 그것이 내가 생각해 낸 것입니다.error: reference to 'CFData' not used to initialize a inout parameter &inBitmapData
알파 블렌드 입력에 필요한 두 버퍼의 데이터를 가리키는 방식을 변경해야했습니다. 이제는 더 이상 충돌하지 않고 운좋게도 속도 향상은 프로파일 러 (vImageAlphaBlend
만 약 CGContextDrawImage
의 3 분의 1이 소요됩니다)에서 검사 할 수 있지만 불행히도 이미지는 흰색 이미지 배경 대신 픽셀 오류가있는 투명한 이미지를 만듭니다.
지금까지 런타임 오류가 더 이상 발생하지 않았지만 결과가 예상 한 것과 같지 않기 때문에 알파 블렌딩 기능을 올바르게 사용하지 않을까 우려됩니다.
먼저 불편을 끼쳐 드려 죄송합니다. 문제를 해결할 수 없습니다. CFDataRef는 CFData의 타입 앨리어스이므로 충돌을 야기하지 않아 어쨌든 CFData로 변경되었습니다. 모든 레이어는 addLayer 함수로 만들어 지므로 미리 곱셈 된 알파가있는 네 개의 동일한 채널을 사용합니다. 내 문제를 게시하기 전에 RGBA (.PremultipliedLast)를 사용했지만 신속한 컴파일러는 vImagePremultipliedAlphaBlend_RGBA8888 매크로를 인식하지 못해 .PremultipliedFirst로 레이어를 만들었고 vImagePremultipliedAlphaBlend_ARGB8888도 시도했습니다. – Enie
또한 vImageBuffer_initWithCGImage 함수에 관해서는 사용 방법을 지적 할 수 있습니까? 나는 이미 여기에 관한 질문을 발견했다 : http://stackoverflow.com/questions/26755978/fatal-error-unexpectedly-found-nil-while-unwrapping-an-optional-value-while-u 마지막 해결책은 해당 데이터로 nil을 사용하여 vImageBuffer 구조체를 만듭니다. vImageBuffer_initWithCGImage가 CGImage 데이터를 nil이 가리키는 곳으로 쓸 수 있는지 확실하지 않습니다. vImageCreateCGImageFromBuffer를 사용하여 vImageBuffer에서 CGImage를 만들려고 할 때 잘못된 액세스 오류가 발생하는 동안 프로그램이 중단됩니다. – Enie
Swift에서 불안정하지만 & inBitmapData를 수행하면 CFDataRef에 대한 포인터를 반환하거나 CFDataGetBytePtr을 반환합니다. (inBitmapData). 이전 버전 인 경우 vImage가 CFDataRef 객체에 대한 포인터가 아니라 픽셀에 대한 포인터를 기대하기 때문에 충돌이 발생할 수 있습니다. 어쨌든 vImageBuffer_initWithCGImage와 vImageBuffer_Init은 모두 할당되었지만 초기화되지 않은 vImage_Buffer를 가져 와서 내용을 채 웁니다. 또한 vImage_Buffer.data에 대한 스토리지를 할당합니다. 작업이 끝나면 (buffer.data)를 비워야합니다. (왜 아직도 CG로 CA 레이어를 합성하고 있는지 궁금합니다.) –