Ios 将视网膜图像转换为视频:“;CGContextScaleCTM:无效的上下文0x0。这是一个严重的错误。”;

Ios 将视网膜图像转换为视频:“;CGContextScaleCTM:无效的上下文0x0。这是一个严重的错误。”;,ios,swift,uiimage,core-graphics,avfoundation,Ios,Swift,Uiimage,Core Graphics,Avfoundation,目标是将一系列视网膜图像转换成一个视频 以下两个函数负责将UIImage写入AvassetWriterInputPixelBufferAdapter。它们可以工作,代码从图像中生成一个看似有效的视频 但是,Xcode会抱怨此错误: CGContextScaleCTM:无效的上下文0x0。这是一个严重的错误。这 应用程序或其使用的库正在使用无效的上下文,并且 从而导致系统稳定性和稳定性的整体退化 可靠性。此通知是出于礼貌:请解决此问题。信息技术 将成为即将进行的更新中的致命错误 大概它在抱怨fil

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

以下两个函数负责将UIImage写入AvassetWriterInputPixelBufferAdapter。它们可以工作,代码从图像中生成一个看似有效的视频

但是,Xcode会抱怨此错误:

CGContextScaleCTM:无效的上下文0x0。这是一个严重的错误。这 应用程序或其使用的库正在使用无效的上下文,并且 从而导致系统稳定性和稳定性的整体退化 可靠性。此通知是出于礼貌:请解决此问题。信息技术 将成为即将进行的更新中的致命错误

大概它在抱怨
fillPixelBufferFromImage
中的行
CGContextScaleCTM(UIGraphicsGetCurrentContext(),scale,scale)
。但是,删除
CGContextScaleCTM(UIGraphicsGetCurrentContext(),scale,scale)
会导致问题。视网膜图像最终呈现为视频内部大小的一半(例如,320x568而不是640x1136)

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

2) 即使是良性的,你怎么能让这个错误消失呢?或者,将视网膜图像渲染成AvassetWriterInputPixelBufferAdapter的正确方法是什么

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)
}
func-appendPixelBufferForImageAtURL(图像:UIImage,PixelBufferAdapter:AvassetWriterInputPixelBufferAdapter,presentationTime:CMTime)->Bool{
var=false
自动释放池{
如果让pixelBufferPool=PixelBufferAdapter.pixelBufferPool{
设pixelBufferPointer=UnsafemeutablePointer.alloc(1)
let状态:CVReturn=CVPixelBufferPoolCreatePixelBuffer(
KCO默认值,
像素缓冲池,
像素缓冲指针
)
如果让pixelBuffer=pixelBufferPointer.memory,其中状态==0{
fillPixelBufferFromImage(图像,pixelBuffer:pixelBuffer)
AppendSucceed=PixelBufferAdapter.appendPixelBuffer(pixelBuffer,带presentationTime:presentationTime)
pixelBufferPointer.destroy()
}否则{
NSLog(“错误:无法从池中分配像素缓冲区”)
}
pixelBufferPointer.dealloc(1)
}
}
返回成功
}
func fillPixelBufferFromImage(图像:UIImage,pixelBuffer:CVPixelBufferRef){
///锁定基址
CVPixelBufferLockBaseAddress(pixelBuffer,0)
//设置上下文的属性
让pixelData=CVPixelBufferGetBaseAddress(pixelBuffer)
设rgbColorSpace=CGColorSpaceCreateDeviceRGB()
让比例=image.scale
设scaledWidth=image.size.width*scale
设scaledHeight=image.size.height*比例
//创建CGBitmapContext
让context=CGBitmapContextCreate(
像素数据,
Int(缩放宽度),
Int(缩放高度),
8.
CVPixelBufferGetBytesPerRow(像素缓冲区),
RGB颜色空间,
CGImageAlphaInfo.PremultipledFirst.rawValue
)
//设置上下文的比例
CGContextScaleCTM(UIGraphicsGetCurrentContext(),缩放,缩放)
//将图像置于上下文中
CGContextDrawImage(上下文,CGRectMake(0,0,scaledWidth,scaledHeight),image.CGImage)
///解锁基址
CVPixelBufferUnlockBaseAddress(pixelBuffer,0)
}

是的,这是一个您应该担心的错误。“这是一个严重错误”和“请解决此问题”的错误消息不是玩笑

这是不正确的:

CGContextScaleCTM(UIGraphicsGetCurrentContext(), scale, scale)
因为这些都不是事实:

  • 您不在UIView的
    -drawRect:
    方法中
  • 您没有调用
    UIGraphicsBeginImageContext
    来设置上下文
  • 您没有手动调用
    UIGraphicsPushContext
  • 因此,就UIKit所知,没有“当前”上下文,因此
    UIGraphicsGetCurrentContext()
    返回nil

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

    CGContextScaleCTM(context, scale, scale)
    

    谢谢,我会试试这个!但是,删除这一行
    CGContextScaleCTM(UIGraphicsGetCurrentContext(),scale,scale)
    会更改渲染图像,使其以1.0的比例渲染(例如,5S上的320x568),而包含它会使图像以2.0的比例渲染。如果你不介意解释的话,它怎么会有效果呢?嗯,CGContextScaleCTM(上下文、比例、比例)似乎不起作用。它生成的图像太大。甚至尝试将
    scaledWidth
    scaledHeight
    更改为不包含刻度,因为看起来可能会出现双重效果,但也失败了。到目前为止,在视频中唯一以正确大小(例如640x1136)渲染图像的是
    CGContextScaleCTM(UIGraphicsGetCurrentContext(),scale,scale)
    。如果
    UIGraphicsGetCurrentContext
    返回非零值,则删除该行将产生效果的唯一方法是。它只是偶尔打印警告信息吗?调用此代码时,您是否在UIView的
    -drawRect:
    方法中?此外,由于您正在缩放CTM,因此应该使用未缩放的大小绘制图像:
    CGContextDrawImage(context,CGRectMake(0,0,image.width,image.height),image.CGImage)
    。(这就是为什么如果您提供一个完整的示例来演示问题,它会很有帮助。您没有在这里显示所有代码,因此我必须猜测您调用它的环境。)你是对的,但是在过去,发布太多的代码引起了其他评论者的愤怒,很难判断正确的级别。将很快发布。它会一致地打印警告消息。而不是在drawRect方法中。