Я пытаюсь альфа-смешивать некоторые layers: [CGImageRef]
в подпрограмме drawLayer(thisLayer: CALayer!, inContext ctx: CGContext!)
моего пользовательского NSView
. До сих пор я использовал CGContextDrawImage()
для рисования этих слоев в контексте drawLayer. Во время профилирования я заметил, что CGContextDrawImage()
требует 70% процессорного времени, поэтому я решил попробовать фреймворк Accelerate. Я изменил код, но он просто вылетает, и я понятия не имею, в чем может быть причина.
Я создаю эти слои следующим образом:
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 всегда один и тот же, а также все слои имеют одинаковый размер, поэтому я не понимаю, почему последняя строка вылетает.
Также я не вижу, как использовать новые удобные функции для создания vImageBuffers непосредственно из CGLayerRefs. Вот почему я делаю это сложным способом.
Любая помощь приветствуется.
РЕДАКТИРОВАТЬ
inBitmapData
действительно содержит данные о пикселях, которые отражают установленный мной цвет фона. Однако отладчик не может po &inBitmapData
и выдает следующее сообщение:
ошибка: ссылка на 'CFData' не используется для инициализации параметра inout &inBitmapData
Поэтому я искал способ получить указатель на inBitmapData. Вот что я придумал:
var bitmapPtr: UnsafeMutablePointer<CFDataRef> = UnsafeMutablePointer<CFDataRef>.alloc(1)
bitmapPtr.initialize(inBitmapData)
Мне также пришлось изменить способ указания моих данных для обоих буферов, которые мне нужны для ввода альфа-смешивания. Теперь он больше не падает, и, к счастью, прирост скорости можно проверить с помощью профилировщика (vImageAlphaBlend
занимает около трети от CGContextDrawImage
), но, к сожалению, изображение приводит к прозрачному изображению с ошибками пикселей вместо белого фона изображения.
Пока я больше не получаю никаких ошибок во время выполнения, но, поскольку результат не такой, как ожидалось, я боюсь, что я все еще неправильно использую функцию альфа-смешивания.