ios - 将视网膜图像转换为视频 : "CGContextScaleCTM: invalid context 0x0. This is a serious error."

标签 ios swift uiimage core-graphics avfoundation

目标是将一系列视网膜图像转换为单个视频。

下面的两个函数负责将 UIImage 写入 AVAssetWriterInputPixelBufferAdaptor。它们起作用了,并且代码从图像中生成了看似有效的视频。

但是,Xcode 会报错:

CGContextScaleCTM: invalid context 0x0. This is a serious error. This application, or a library it uses, is using an invalid context and is thereby contributing to an overall degradation of system stability and reliability. This notice is a courtesy: please fix this problem. It will become a fatal error in an upcoming update.

据推测,它是在提示 fillPixelBufferFromImage 中的行 CGContextScaleCTM(UIGraphicsGetCurrentContext(), scale, scale)。但是,删除 CGContextScaleCTM(UIGraphicsGetCurrentContext(), scale, scale) 会导致问题。视网膜图像最终在视频中以一半的大小渲染(例如,320x568 而不是 640x1136)。

1) 这是一个值得担心的错误吗?其他 SO 帖子建议不要。

2) 即使是良性的,你如何才能让这个错误消失?或者将视网膜图像渲染到 AVAssetWriterInputPixelBufferAdaptor 中的正确方法是什么?

func appendPixelBufferForImageAtURL(image: UIImage, pixelBufferAdaptor: AVAssetWriterInputPixelBufferAdaptor, presentationTime: CMTime) -> Bool {
    var appendSucceeded = false

    autoreleasepool {
        if  let pixelBufferPool = pixelBufferAdaptor.pixelBufferPool {
            let pixelBufferPointer = UnsafeMutablePointer<CVPixelBuffer?>.alloc(1)
            let status: CVReturn = CVPixelBufferPoolCreatePixelBuffer(
                kCFAllocatorDefault,
                pixelBufferPool,
                pixelBufferPointer
            )

            if let pixelBuffer = pixelBufferPointer.memory where status == 0 {
                fillPixelBufferFromImage(image, pixelBuffer: pixelBuffer)
                appendSucceeded = pixelBufferAdaptor.appendPixelBuffer(pixelBuffer, withPresentationTime: presentationTime)
                pixelBufferPointer.destroy()
            } else {
                NSLog("Error: Failed to allocate pixel buffer from pool")
            }

            pixelBufferPointer.dealloc(1)
        }
    }

    return appendSucceeded
}


func fillPixelBufferFromImage(image: UIImage, pixelBuffer: CVPixelBufferRef) {
    /// Lock base address
    CVPixelBufferLockBaseAddress(pixelBuffer, 0)

    // Set properties for context
    let pixelData = CVPixelBufferGetBaseAddress(pixelBuffer)
    let rgbColorSpace = CGColorSpaceCreateDeviceRGB()
    let scale = image.scale
    let scaledWidth = image.size.width * scale
    let scaledHeight = image.size.height * scale

    // Create CGBitmapContext
    let context = CGBitmapContextCreate(
        pixelData,
        Int(scaledWidth),
        Int(scaledHeight),
        8,
        CVPixelBufferGetBytesPerRow(pixelBuffer),
        rgbColorSpace,
        CGImageAlphaInfo.PremultipliedFirst.rawValue
    )

    // Set scale for context
    CGContextScaleCTM(UIGraphicsGetCurrentContext(), scale, scale)

    // Draw image into context
    CGContextDrawImage(context, CGRectMake(0, 0, scaledWidth, scaledHeight), image.CGImage)

    /// Unlock base address
    CVPixelBufferUnlockBaseAddress(pixelBuffer, 0)
}

最佳答案

是的,这是一个你应该担心的错误。错误消息说“这是一个严重的错误。”并且“请解决这个问题”不是开玩笑。

这是不正确的:

CGContextScaleCTM(UIGraphicsGetCurrentContext(), scale, scale)

因为这些都不是这样的:

  1. 您不在 UIView 的 -drawRect: 方法中
  2. 您没有调用 UIGraphicsBeginImageContext 来设置上下文
  3. 您没有手动调用 UIGraphicsPushContext

因此,据 UIKit 所知,不存在“当前”上下文,因此 UIGraphicsGetCurrentContext() 返回 nil。

您自己创建了位图上下文,因此您应该将比例应用于该上下文:

CGContextScaleCTM(context, scale, scale)

关于ios - 将视网膜图像转换为视频 : "CGContextScaleCTM: invalid context 0x0. This is a serious error.",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36414782/

相关文章:

ios - 在 iOS 中创建消息屏幕

ios - 在世界地图上任何地方的 Mapbox 上实现相同大小的正方形/像素?

json - (Swift) twilio post 请求使用 alamofire 设置属性

swift - 使用 Where 语句从 Firebase 计算 Swift 中的记录

ios - UIImage 显示蓝色矩形而不是 JPEG 图像

iphone - 如何从 UIImage 获取 CGContextRef?

iphone - Facebook iPhone 应用程序-启动图标效果

ios - Xcode 警告 : no rule to Process file when build phases has this file?

swift - 使用 AES 加密在 Swift 中加密/解密 UIImage

iphone - 将 PDF 加载到 UIImage 或 UIImageView 中?