Skip to content

Instantly share code, notes, and snippets.

@cyndibaby905
Created July 15, 2014 02:43
Show Gist options
  • Save cyndibaby905/7be31d1306038dc83c70 to your computer and use it in GitHub Desktop.
Save cyndibaby905/7be31d1306038dc83c70 to your computer and use it in GitHub Desktop.
- (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