UIImage获取CVPixelBuffer去除Alpha
UIImage obtaining CVPixelBuffer Removes Alpha
下面的函数从 UIImage
中接收一个 UIImage
和 returns 一个 CVPixelBuffer
,但它删除了 alpha 通道。
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))
它会打印
Optional
- some : UIExtendedSRGBColorSpace 0 0 0 0
但是生成的图像有黑色背景。
我也试过使用 CGImageAlphaInfo.premultipliedLast.rawValue
但这导致图像是蓝色的,所以我假设 RGBA
到 ARGB
正在交换。但是,具有讽刺意味的是,这意味着 ARGB
中的 B 是 255,这表明 RGBA
中的 A 将是 255,它应该是 0。
如何在使用 CGContext
时正确地将 UIImage
alpha 转换为 CVPixelBuffer
?
编辑 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
版本则可以。
很遗憾,我对这个主题的讨论范围太窄了(具有讽刺意味的是,大多数问题都被认为太宽泛了)。
我试图从 AVCaptureSession
和 AVAssetWriter
一起创建一个视频,其中一些图像有一个深度图,然后我会制作它以将一些像素变成清晰的颜色。好吧,通过一些研究,我发现对于图像和显示它们,alpha 通道是保持不变的。但是,对于视频,这是不可能的。
https://andreygordeev.com/2017/07/01/video-with-transparent-background-ios/
https://github.com/aframevr/aframe/issues/3205
https://www.reddit.com/r/swift/comments/3cw4le/is_it_possible_to_play_a_video_with_an_alpha/
任何人,我的下一个目标是按照某些答案的描述进行 ChromaKey
- 或者是对我的特征应用深度图的掩蔽。
下面的函数从 UIImage
中接收一个 UIImage
和 returns 一个 CVPixelBuffer
,但它删除了 alpha 通道。
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))
它会打印
Optional - some : UIExtendedSRGBColorSpace 0 0 0 0
但是生成的图像有黑色背景。
我也试过使用 CGImageAlphaInfo.premultipliedLast.rawValue
但这导致图像是蓝色的,所以我假设 RGBA
到 ARGB
正在交换。但是,具有讽刺意味的是,这意味着 ARGB
中的 B 是 255,这表明 RGBA
中的 A 将是 255,它应该是 0。
如何在使用 CGContext
时正确地将 UIImage
alpha 转换为 CVPixelBuffer
?
编辑 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
版本则可以。
很遗憾,我对这个主题的讨论范围太窄了(具有讽刺意味的是,大多数问题都被认为太宽泛了)。
我试图从 AVCaptureSession
和 AVAssetWriter
一起创建一个视频,其中一些图像有一个深度图,然后我会制作它以将一些像素变成清晰的颜色。好吧,通过一些研究,我发现对于图像和显示它们,alpha 通道是保持不变的。但是,对于视频,这是不可能的。
任何人,我的下一个目标是按照某些答案的描述进行 ChromaKey
- 或者是对我的特征应用深度图的掩蔽。