Created
July 15, 2014 02:43
-
-
Save cyndibaby905/7be31d1306038dc83c70 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
- (UIImage *)alteredImageFromSampleBuffer:(CMSampleBufferRef)sampleBuffer | |
{ | |
// Get a reference to the buffer, lock the address, and get a pointer to its data. Easy peasy. | |
CVImageBufferRef imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer); | |
CVPixelBufferLockBaseAddress(imageBuffer, 0); | |
void *sourceData = CVPixelBufferGetBaseAddress(imageBuffer); | |
// Set a bunch of variables we need. The "radius" for the blur kernel needs to be positive and odd. The permute map maps the BGRA channels of the buffer to the ARGB that vImage needs. | |
size_t bytesPerRow = CVPixelBufferGetBytesPerRow(imageBuffer); | |
size_t width = CVPixelBufferGetWidth(imageBuffer); | |
size_t height = CVPixelBufferGetHeight(imageBuffer); | |
size_t bytesPerPixel = 4; | |
uint32_t radius = (int)_slider.value % 2 == 0 ? (int)_slider.value + 1 : (int)_slider.value; | |
uint8_t permuteMap[4] = { 3, 2, 1, 0}; | |
// malloc some memories and create some buffers. | |
UInt8 *destinationData1 = malloc(width * height * bytesPerPixel); | |
UInt8 *destinationData2 = malloc(width * height * bytesPerPixel); | |
vImage_Buffer src = {sourceData, height, width, bytesPerRow}; | |
vImage_Buffer dst1 = {destinationData1, height, width, bytesPerRow}; | |
vImage_Buffer dst2 = {destinationData2, height, width, bytesPerRow}; | |
// Map the channels and do two box blurs for that nice pseudo-gaussian look. | |
vImagePermuteChannels_ARGB8888(&src, &dst1, permuteMap, kvImageNoFlags); | |
vImageBoxConvolve_ARGB8888(&dst1, &dst2, NULL, 0, 0, radius, radius, NULL, kvImageEdgeExtend); | |
vImageBoxConvolve_ARGB8888(&dst2, &dst1, NULL, 0, 0, radius, radius, NULL, kvImageEdgeExtend); | |
// Turn the destination buffer into a CGImageRef and wrap that sucker up in an UIImage. | |
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); | |
CGContextRef context = CGBitmapContextCreate(destinationData1, width, height, 8, bytesPerRow, colorSpace, kCGImageAlphaPremultipliedFirst); | |
CGImageRef quartzImage = CGBitmapContextCreateImage(context); | |
CVPixelBufferUnlockBaseAddress(imageBuffer,0); | |
UIImage *image = [UIImage imageWithCGImage:quartzImage | |
scale:[[UIScreen mainScreen] scale] | |
orientation:UIImageOrientationUp]; | |
// Clean up and return. | |
CGContextRelease(context); | |
CGColorSpaceRelease(colorSpace); | |
CGImageRelease(quartzImage); | |
free(destinationData1); | |
free(destinationData2); | |
return image; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment