是否可以使用本机 iOS API 加载 24 位 BMP?
Is it possible to load a 24-bits BMP with a native iOS API?
我正在为一个设备编写一个应用程序,该设备 API 为我们提供了一个 const char*
字节数组,对应于具有 24 位色深的 BMP 的像素数据,Core Graphics 不支持,所以我循环遍历字节,为 alpha 通道添加第四个字节,然后使用 CGImageAlphaInfo.noneSkipLast
:
跳过它
let imageProperties = /* call to the device API that returns the image metadata */
let imageData = UnsafeMutablePointer<CChar>(mutating: /* call to the device API that returns the pointer */)
let imageWidth = Int(imageProperties.width)
let imageHeight = Int(imageProperties.height)
let bytesPerPixelWithoutAlpha = 3
let imageSize = imageWidth * imageHeight * bytesPerPixelWithoutAlpha
var imageDataWithAlpha = [CChar]()
for i in stride(from: 0, to: imageSize, by: bytesPerPixelWithoutAlpha) {
imageDataWithAlpha.append(imageData![i])
imageDataWithAlpha.append(imageData![i + 1])
imageDataWithAlpha.append(imageData![i + 2])
imageDataWithAlpha.append(127)
}
let bytesPerPixelWithAlpha = 4
let bytesPerRow = imageWidth * bytesPerPixelWithAlpha
let imageDataWithAlphaPointer = UnsafeMutablePointer<CChar>.allocate(capacity: imageDataWithAlpha.count)
imageDataWithAlphaPointer.initialize(from: &imageDataWithAlpha, count: imageDataWithAlpha.count)
let bmp = CGContext(
data: imageDataWithAlphaPointer,
width: imageWidth,
height: imageHeight,
bitsPerComponent: 8,
bytesPerRow: bytesPerRow,
space: CGColorSpaceCreateDeviceRGB(),
bitmapInfo: CGImageAlphaInfo.noneSkipLast.rawValue
)!.makeImage()!
bmp
被传递给 CIContext().writeJPEGRepresentation
以将 JPEG 写入磁盘,它可以工作,但我的代码有味道,我敢打赌我可以使用其他一些 API我的循环
我认为您可以用适当的格式将数据包装成 CVPixelBuffer
并将其传递给 Core Image。类似的东西:
var pixelBuffer: CVPixelBuffer?
let result = CVPixelBufferCreateWithBytes(kCFAllocatorDefault,
imageWidth,
imageHeight,
kCVPixelFormatType_24RGB,
imageData,
3 * imageWidth,
nil,
nil,
nil,
&pixelBuffer)
guard result == kCVReturnSuccess, let pixelBuffer = pixelBuffer else {
fatalError()
}
let image = CIImage(cvPixelBuffer: pixelBuffer)
// ...
Core Image 应根据需要自动填充 alpha 通道。
我正在为一个设备编写一个应用程序,该设备 API 为我们提供了一个 const char*
字节数组,对应于具有 24 位色深的 BMP 的像素数据,Core Graphics 不支持,所以我循环遍历字节,为 alpha 通道添加第四个字节,然后使用 CGImageAlphaInfo.noneSkipLast
:
let imageProperties = /* call to the device API that returns the image metadata */
let imageData = UnsafeMutablePointer<CChar>(mutating: /* call to the device API that returns the pointer */)
let imageWidth = Int(imageProperties.width)
let imageHeight = Int(imageProperties.height)
let bytesPerPixelWithoutAlpha = 3
let imageSize = imageWidth * imageHeight * bytesPerPixelWithoutAlpha
var imageDataWithAlpha = [CChar]()
for i in stride(from: 0, to: imageSize, by: bytesPerPixelWithoutAlpha) {
imageDataWithAlpha.append(imageData![i])
imageDataWithAlpha.append(imageData![i + 1])
imageDataWithAlpha.append(imageData![i + 2])
imageDataWithAlpha.append(127)
}
let bytesPerPixelWithAlpha = 4
let bytesPerRow = imageWidth * bytesPerPixelWithAlpha
let imageDataWithAlphaPointer = UnsafeMutablePointer<CChar>.allocate(capacity: imageDataWithAlpha.count)
imageDataWithAlphaPointer.initialize(from: &imageDataWithAlpha, count: imageDataWithAlpha.count)
let bmp = CGContext(
data: imageDataWithAlphaPointer,
width: imageWidth,
height: imageHeight,
bitsPerComponent: 8,
bytesPerRow: bytesPerRow,
space: CGColorSpaceCreateDeviceRGB(),
bitmapInfo: CGImageAlphaInfo.noneSkipLast.rawValue
)!.makeImage()!
bmp
被传递给 CIContext().writeJPEGRepresentation
以将 JPEG 写入磁盘,它可以工作,但我的代码有味道,我敢打赌我可以使用其他一些 API我的循环
我认为您可以用适当的格式将数据包装成 CVPixelBuffer
并将其传递给 Core Image。类似的东西:
var pixelBuffer: CVPixelBuffer?
let result = CVPixelBufferCreateWithBytes(kCFAllocatorDefault,
imageWidth,
imageHeight,
kCVPixelFormatType_24RGB,
imageData,
3 * imageWidth,
nil,
nil,
nil,
&pixelBuffer)
guard result == kCVReturnSuccess, let pixelBuffer = pixelBuffer else {
fatalError()
}
let image = CIImage(cvPixelBuffer: pixelBuffer)
// ...
Core Image 应根据需要自动填充 alpha 通道。