CGImage 直接到 CVPixelBuffer

从image到CVPixelBuffer需要注意性能,如果使用context的话和使用memcpy都有一样的性能支出,但是使用CVPixelBufferCreateWithBytes这个可以在时间上提高好几个数量级别,这是因为这里没有渲染也没有内存拷贝能耗时的操作而只是将data的指针进行了修改哦。

- (CVPixelBufferRef)pixelBufferFaster{
    
    CVPixelBufferRef pxbuffer = NULL;
    NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:
                             [NSNumber numberWithBool:YES], kCVPixelBufferCGImageCompatibilityKey,
                             [NSNumber numberWithBool:YES], kCVPixelBufferCGBitmapContextCompatibilityKey,
                             nil];
    
    size_t width =  CGImageGetWidth(self.image);
    size_t height = CGImageGetHeight(self.image);
    size_t bytesPerRow = CGImageGetBytesPerRow(self.image);

    CFDataRef  dataFromImageDataProvider = CGDataProviderCopyData(CGImageGetDataProvider(self.image));
    GLubyte  *imageData = (GLubyte *)CFDataGetBytePtr(dataFromImageDataProvider);
    
    CVPixelBufferCreateWithBytes(kCFAllocatorDefault,width,height,kCVPixelFormatType_32ARGB,imageData,bytesPerRow,NULL,NULL,(__bridge CFDictionaryRef)options,&pxbuffer);
  
    CFRelease(dataFromImageDataProvider);

    return pxbuffer;

}

- (CVPixelBufferRef)pixelBufferFromCGImageWithPool:(CVPixelBufferPoolRef)pixelBufferPool
{

    CVPixelBufferRef pxbuffer = NULL;
    NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:
                             [NSNumber numberWithBool:YES], kCVPixelBufferCGImageCompatibilityKey,
                             [NSNumber numberWithBool:YES], kCVPixelBufferCGBitmapContextCompatibilityKey,
                             nil];
    
    size_t width =  CGImageGetWidth(self.image);
    size_t height = CGImageGetHeight(self.image);
    size_t bytesPerRow = CGImageGetBytesPerRow(self.image);
    size_t bitsPerComponent = CGImageGetBitsPerComponent(self.image);
    CGBitmapInfo bitmapInfo = CGImageGetBitmapInfo(self.image);
    void *pxdata = NULL;
    
    
    if (pixelBufferPool == NULL)
        NSLog(@"pixelBufferPool is null!");
    
    CVReturn status = CVPixelBufferPoolCreatePixelBuffer (NULL, pixelBufferPool, &pxbuffer);
    if (pxbuffer == NULL) {
        status = CVPixelBufferCreate(kCFAllocatorDefault, width,
                                              height, kCVPixelFormatType_32ARGB, (__bridge CFDictionaryRef) options,
                                              &pxbuffer);
     }
    
    NSParameterAssert(status == kCVReturnSuccess && pxbuffer != NULL);
    CVPixelBufferLockBaseAddress(pxbuffer, 0);
    pxdata = CVPixelBufferGetBaseAddress(pxbuffer);
   
    NSParameterAssert(pxdata != NULL);
    
    if(1){
    
        CGColorSpaceRef rgbColorSpace = CGColorSpaceCreateDeviceRGB();
        CGContextRef context = CGBitmapContextCreate(pxdata, width,
                                                     height,bitsPerComponent,bytesPerRow, rgbColorSpace,
                                                     bitmapInfo);
        NSParameterAssert(context);
        CGContextConcatCTM(context, CGAffineTransformMakeRotation(0));
        CGContextDrawImage(context, CGRectMake(0, 0, width,height), self.image);
        CGColorSpaceRelease(rgbColorSpace);
        CGContextRelease(context);
    }else{
        
     
        CFDataRef  dataFromImageDataProvider = CGDataProviderCopyData(CGImageGetDataProvider(self.image));
        CFIndex length = CFDataGetLength(dataFromImageDataProvider);
        GLubyte  *imageData = (GLubyte *)CFDataGetBytePtr(dataFromImageDataProvider);
        memcpy(pxdata,imageData,length);

        CFRelease(dataFromImageDataProvider);
    }
    
    
    return pxbuffer;

}


你可能感兴趣的:(ios)