Функция ниже принимает UIImage
и возвращает CVPixelBuffer
из UIImage
, но удаляет альфа-канал.
class func pixelBufferFromImage(image: UIImage, pixelBufferPool: CVPixelBufferPool, size: CGSize) -> CVPixelBuffer {
var pixelBufferOut: CVPixelBuffer?
let status = CVPixelBufferPoolCreatePixelBuffer(kCFAllocatorDefault, pixelBufferPool, &pixelBufferOut)
if status != kCVReturnSuccess {
fatalError("CVPixelBufferPoolCreatePixelBuffer() failed")
}
let pixelBuffer = pixelBufferOut!
CVPixelBufferLockBaseAddress(pixelBuffer, [])
let data = CVPixelBufferGetBaseAddress(pixelBuffer)
let rgbColorSpace = CGColorSpaceCreateDeviceRGB()
let context = CGContext(data: data, width: Int(size.width), height: Int(size.height),
bitsPerComponent: 8, bytesPerRow: CVPixelBufferGetBytesPerRow(pixelBuffer), space: rgbColorSpace, bitmapInfo: CGImageAlphaInfo.premultipliedFirst.rawValue)
context!.clear(CGRect(x: 0, y: 0, width: size.width, height: size.height))
let horizontalRatio = size.width / image.size.width
let verticalRatio = size.height / image.size.height
//aspectRatio = max(horizontalRatio, verticalRatio) // ScaleAspectFill
let aspectRatio = min(horizontalRatio, verticalRatio) // ScaleAspectFit
let newSize = CGSize(width: image.size.width * aspectRatio, height: image.size.height * aspectRatio)
let x = newSize.width < size.width ? (size.width - newSize.width) / 2 : 0
let y = newSize.height < size.height ? (size.height - newSize.height) / 2 : 0
context!.draw(image.cgImage!, in: CGRect(x: x, y: y, width: newSize.width, height: newSize.height))
CVPixelBufferUnlockBaseAddress(pixelBuffer, [])
return pixelBuffer
}
- Я знаю, что исходное изображение имеет несколько пикселей с определенным
alpha = 0
, потому что, если я сделаюpo image.pixelColor(atLocation: CGPoint(x: 0, y: 0))
, оно напечатает
Необязательно - некоторые: UIExtendedSRGBColorSpace 0 0 0 0
но результирующее изображение имеет черный фон.
Я также пытался использовать CGImageAlphaInfo.premultipliedLast.rawValue
, но это приводит к тому, что изображение становится синим, поэтому я предполагаю, что RGBA
на ARGB
меняются местами. Но, по иронии судьбы, это будет означать, что B в ARGB
равно 255, что указывает на то, что в RGBA
A будет 255, а должно быть 0.
Как я могу правильно перевести альфа-канал UIImage
в CVPixelBuffer
при использовании CGContext
?
Редактировать 1:
Вот мой код для моего pixelBufferPool
.
func createPixelBufferAdaptor() {
let pixelFormatRGBA = kCVPixelFormatType_32RGBA //Fails
let pixelFormatARGB = kCVPixelFormatType_32ARGB //Works
let sourcePixelBufferAttributesDictionary = [
kCVPixelBufferPixelFormatTypeKey as String: NSNumber(value: pixelFormatARGB),
kCVPixelBufferWidthKey as String: NSNumber(value: Float(renderSettings.width)),
kCVPixelBufferHeightKey as String: NSNumber(value: Float(renderSettings.height))
]
pixelBufferAdaptor = AVAssetWriterInputPixelBufferAdaptor(assetWriterInput: videoWriterInput,
sourcePixelBufferAttributes: sourcePixelBufferAttributesDictionary)
}
Это работает только тогда, когда я использую kCVPixelFormatType_32ARGB
. Что я имею в виду под работой, так это то, что когда я пытаюсь использовать буферный пул
let status = CVPixelBufferPoolCreatePixelBuffer(kCFAllocatorDefault, pixelBufferPool, &pixelBufferOut)
if status != kCVReturnSuccess {
fatalError("CVPixelBufferPoolCreatePixelBuffer() failed")
}
это не работает, если я использую версию RGBA
, но работает, если я использую версию ARGB
.
pixelBufferPool
. Вы передаете туда в атрибутах ключkCVPixelBufferPixelFormatTypeKey
какkCVPixelFormatType_32RGBA
? - person Eugene Dudnyk   schedule 06.08.2019kCVPixelFormatType_32ARGB which makes sense why my
A`, это будет 255, но это не имеет смысла, потому что у меня на картинке был синий цвет, аB
должен быть 0. Тем не менее, я попытался переключиться наRGBA
, чтобы проверить свою теорию, и это привело к сбою.Edit 1
выше описывает, что происходит. Спасибо! - person impression7vx   schedule 06.08.2019