How to turn a CVPixelBuffer into a UIImage?

前端 未结 6 1772
梦毁少年i
梦毁少年i 2020-11-28 21:55

I\'m having some problems getting a UIIMage from a CVPixelBuffer. This is what I am trying:

CVPixelBufferRef pixelBuffer = CMSampleBufferGetImageBuffer(imag         


        
6条回答
  •  难免孤独
    2020-11-28 22:43

    The previous methods led me to have CG Raster Data leak. This method of conversion did not leak for me:

    @autoreleasepool {
    
        CGImageRef cgImage = NULL;
        OSStatus res = CreateCGImageFromCVPixelBuffer(pixelBuffer,&cgImage);
        if (res == noErr){
            UIImage *image= [UIImage imageWithCGImage:cgImage scale:1.0 orientation:UIImageOrientationUp];
    
        }
        CGImageRelease(cgImage);
    }
    
    
        static OSStatus CreateCGImageFromCVPixelBuffer(CVPixelBufferRef pixelBuffer, CGImageRef *imageOut)
        {
            OSStatus err = noErr;
            OSType sourcePixelFormat;
            size_t width, height, sourceRowBytes;
            void *sourceBaseAddr = NULL;
            CGBitmapInfo bitmapInfo;
            CGColorSpaceRef colorspace = NULL;
            CGDataProviderRef provider = NULL;
            CGImageRef image = NULL;
    
            sourcePixelFormat = CVPixelBufferGetPixelFormatType( pixelBuffer );
            if ( kCVPixelFormatType_32ARGB == sourcePixelFormat )
                bitmapInfo = kCGBitmapByteOrder32Big | kCGImageAlphaNoneSkipFirst;
            else if ( kCVPixelFormatType_32BGRA == sourcePixelFormat )
                bitmapInfo = kCGBitmapByteOrder32Little | kCGImageAlphaNoneSkipFirst;
            else
                return -95014; // only uncompressed pixel formats
    
            sourceRowBytes = CVPixelBufferGetBytesPerRow( pixelBuffer );
            width = CVPixelBufferGetWidth( pixelBuffer );
            height = CVPixelBufferGetHeight( pixelBuffer );
    
            CVPixelBufferLockBaseAddress( pixelBuffer, 0 );
            sourceBaseAddr = CVPixelBufferGetBaseAddress( pixelBuffer );
    
            colorspace = CGColorSpaceCreateDeviceRGB();
    
            CVPixelBufferRetain( pixelBuffer );
            provider = CGDataProviderCreateWithData( (void *)pixelBuffer, sourceBaseAddr, sourceRowBytes * height, ReleaseCVPixelBuffer);
            image = CGImageCreate(width, height, 8, 32, sourceRowBytes, colorspace, bitmapInfo, provider, NULL, true, kCGRenderingIntentDefault);
    
            if ( err && image ) {
                CGImageRelease( image );
                image = NULL;
            }
            if ( provider ) CGDataProviderRelease( provider );
            if ( colorspace ) CGColorSpaceRelease( colorspace );
            *imageOut = image;
            return err;
        }
    
        static void ReleaseCVPixelBuffer(void *pixel, const void *data, size_t size)
        {
            CVPixelBufferRef pixelBuffer = (CVPixelBufferRef)pixel;
            CVPixelBufferUnlockBaseAddress( pixelBuffer, 0 );
            CVPixelBufferRelease( pixelBuffer );
        }
    

提交回复
热议问题