iOS 14 ARKit CapturedImage JPEG 转换 HEIC 警告
iOS 14 ARKit CapturedImage JPEG Conversion HEIC Warning
TL;DR:iOS14 中的 ARKit capturedImage
发生了一些变化,我们无法使其适应我们的流程。
Built with Xcode 12 GM, tested on iPhone 6S 14.0.
我们实施了一个流程,将 ARFrame
转换为 Data
,这非常适合尚未升级到 iOS14 的设备。
我们得到了 ciImage
这样的:
extension ARFrame {
var ciImage: CIImage { CIImage(cvPixelBuffer: capturedImage) }
}
我们输入 ImageConverter
:
public class ImageConverter {
lazy var imageContext = CIContext(mtlDevice: MTLCreateSystemDefaultDevice()!)
lazy var colorSpace = CGColorSpace(name: CGColorSpace.sRGB)
public func jpgData(for image: CIImage) -> Data {
guard let colorSpace = colorSpace else { return Data() }
if let jpegRepresentation = imageContext.jpegRepresentation(of: image,
colorSpace: image.colorSpace ?? colorSpace) {
return jpegRepresentation
} else {
return Data()
}
}
}
所以,问题是,当我们调用.jpegRepresentation
时,它给出了一个警告:
findWriterForType:128: unsupported file format 'public.heic'
虽然 jpegRepresentation
不是零,但它不适用于我们的服务器,它需要一个 jpeg 数据(它仍然适用于 iOS13.7 或以下设备)。
到目前为止我们尝试了什么:
if let heifRepresentation = imageContext.heifRepresentation(of: image,
format: .RGBA8,
colorSpace: image.colorSpace ?? colorSpace) {
return heifRepresentation
}
returns nil,并抛出与 .jpegRepresentation
相同的错误。也试过其他格式,无果。
问题出在用.jpegRepresentation
创建的JPEG数据格式。
这是 iPhone XS - iOS13 与 iPhone 6S - iOS14 之间的区别:
终端输出:
➜ file testiOS13.jpeg
testiOS13.jpeg: JPEG image data, JFIF
standard 1.01, aspect ratio, density 72x72, segment length 16, Exif
Standard: [TIFF image data, big-endian, direntries=1], baseline,
precision 8, 600x800, components 3
➜ file testiOS14.jpeg
testiOS14.jpeg: JPEG image data, Exif standard: [TIFF image data,
big-endian, direntries=5, xresolution=74, yresolution=82,
resolutionunit=2], baseline, precision 8, 412x733, components 3
iOS 14 张 ARKit 图片缺少 JFIF 标准 1.01。
在 CGImage
和 Data
之间有一个环(以及可用性检查以防 iOS 13.7 或更低版本出现问题):
public func jpgData(for image: CIImage, with size: CGSize) -> Data {
guard #available(iOS 14.0, *) else { return jpgData(for: image) }
guard let cgImage = imageContext.createCGImage(image, from: CGRect(origin: .zero, size: size)) else { return jpgData(for: image) }
let data = NSMutableData()
guard let imageDestination = CGImageDestinationCreateWithData(data, AVFileType.jpg as CFString, 1, nil) else { return jpgData(for: image) }
CGImageDestinationAddImage(imageDestination, cgImage, nil)
guard CGImageDestinationFinalize(imageDestination) else { return jpgData(for: image) }
return data as Data
}
private func jpgData(for image: CIImage) -> Data {
guard let colorSpace = colorSpace else { return Data() }
return imageContext.jpegRepresentation(of: image, colorSpace: colorSpace) ?? Data()
}
最新变化:
终端输出:
➜ file testiOS14_New.jpeg
testiOS14_New.jpeg: JPEG image data, JFIF standard
1.01, aspect ratio, density 72x72, segment length 16, Exif Standard: [TIFF image data, big-endian, direntries=1], baseline, precision 8,
413x734, components 3
我也注意到了一些奇怪的地方,执行几乎相同的流程,但将 ARFrame 保存为 heic 文件:
在 iOS 14 上,它在某些内部方法中完全崩溃,并使 heifRepresentation 变得无用。
下面是处理转换的代码片段:
guard let ciImage = CIImage(image: self),
let colorSpace = ciImage.colorSpace else {
throw HEICError.heicNotSupported
}
let ciContext = CIContext()
do {
try ciContext.writeHEIFRepresentation(of: ciImage, to: urlFilePath, format: ciContext.workingFormat, colorSpace: colorSpace, options: [kCGImageDestinationLossyCompressionQuality as CIImageRepresentationOption: 1.0])
} catch {
print("Error is \(error.localizedDescription)")
throw HEICError.saveFail
}
提醒一下,这在 iOS14 之前是完美的。我已经尝试了很多编写 heic 文件的方法,但我遇到了致命的崩溃:
vExtractChannel_ARGB8888 BAD_EXEC
这里肯定有猫腻。
有什么事情会更新
TL;DR:iOS14 中的 ARKit capturedImage
发生了一些变化,我们无法使其适应我们的流程。
Built with Xcode 12 GM, tested on iPhone 6S 14.0.
我们实施了一个流程,将 ARFrame
转换为 Data
,这非常适合尚未升级到 iOS14 的设备。
我们得到了 ciImage
这样的:
extension ARFrame {
var ciImage: CIImage { CIImage(cvPixelBuffer: capturedImage) }
}
我们输入 ImageConverter
:
public class ImageConverter {
lazy var imageContext = CIContext(mtlDevice: MTLCreateSystemDefaultDevice()!)
lazy var colorSpace = CGColorSpace(name: CGColorSpace.sRGB)
public func jpgData(for image: CIImage) -> Data {
guard let colorSpace = colorSpace else { return Data() }
if let jpegRepresentation = imageContext.jpegRepresentation(of: image,
colorSpace: image.colorSpace ?? colorSpace) {
return jpegRepresentation
} else {
return Data()
}
}
}
所以,问题是,当我们调用.jpegRepresentation
时,它给出了一个警告:
findWriterForType:128: unsupported file format 'public.heic'
虽然 jpegRepresentation
不是零,但它不适用于我们的服务器,它需要一个 jpeg 数据(它仍然适用于 iOS13.7 或以下设备)。
到目前为止我们尝试了什么:
if let heifRepresentation = imageContext.heifRepresentation(of: image,
format: .RGBA8,
colorSpace: image.colorSpace ?? colorSpace) {
return heifRepresentation
}
returns nil,并抛出与 .jpegRepresentation
相同的错误。也试过其他格式,无果。
问题出在用.jpegRepresentation
创建的JPEG数据格式。
这是 iPhone XS - iOS13 与 iPhone 6S - iOS14 之间的区别:
终端输出:
➜ file testiOS13.jpeg
testiOS13.jpeg: JPEG image data, JFIF standard 1.01, aspect ratio, density 72x72, segment length 16, Exif Standard: [TIFF image data, big-endian, direntries=1], baseline, precision 8, 600x800, components 3
➜ file testiOS14.jpeg
testiOS14.jpeg: JPEG image data, Exif standard: [TIFF image data, big-endian, direntries=5, xresolution=74, yresolution=82, resolutionunit=2], baseline, precision 8, 412x733, components 3
iOS 14 张 ARKit 图片缺少 JFIF 标准 1.01。
在 CGImage
和 Data
之间有一个环(以及可用性检查以防 iOS 13.7 或更低版本出现问题):
public func jpgData(for image: CIImage, with size: CGSize) -> Data {
guard #available(iOS 14.0, *) else { return jpgData(for: image) }
guard let cgImage = imageContext.createCGImage(image, from: CGRect(origin: .zero, size: size)) else { return jpgData(for: image) }
let data = NSMutableData()
guard let imageDestination = CGImageDestinationCreateWithData(data, AVFileType.jpg as CFString, 1, nil) else { return jpgData(for: image) }
CGImageDestinationAddImage(imageDestination, cgImage, nil)
guard CGImageDestinationFinalize(imageDestination) else { return jpgData(for: image) }
return data as Data
}
private func jpgData(for image: CIImage) -> Data {
guard let colorSpace = colorSpace else { return Data() }
return imageContext.jpegRepresentation(of: image, colorSpace: colorSpace) ?? Data()
}
最新变化:
终端输出:
➜ file testiOS14_New.jpeg
testiOS14_New.jpeg: JPEG image data, JFIF standard 1.01, aspect ratio, density 72x72, segment length 16, Exif Standard: [TIFF image data, big-endian, direntries=1], baseline, precision 8, 413x734, components 3
我也注意到了一些奇怪的地方,执行几乎相同的流程,但将 ARFrame 保存为 heic 文件: 在 iOS 14 上,它在某些内部方法中完全崩溃,并使 heifRepresentation 变得无用。
下面是处理转换的代码片段:
guard let ciImage = CIImage(image: self),
let colorSpace = ciImage.colorSpace else {
throw HEICError.heicNotSupported
}
let ciContext = CIContext()
do {
try ciContext.writeHEIFRepresentation(of: ciImage, to: urlFilePath, format: ciContext.workingFormat, colorSpace: colorSpace, options: [kCGImageDestinationLossyCompressionQuality as CIImageRepresentationOption: 1.0])
} catch {
print("Error is \(error.localizedDescription)")
throw HEICError.saveFail
}
提醒一下,这在 iOS14 之前是完美的。我已经尝试了很多编写 heic 文件的方法,但我遇到了致命的崩溃:
vExtractChannel_ARGB8888 BAD_EXEC
这里肯定有猫腻。
有什么事情会更新