Forked from podkovyrin/CMSampleBufferRef_to_vImage.m
Created
November 25, 2022 10:52
-
-
Save antranapp/0a9d940e5c7b247b2d85e70cced27ce8 to your computer and use it in GitHub Desktop.
CMSampleBufferRef to vImage and resize
This file contains 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
CVImageBufferRef imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer); | |
CVPixelBufferLockBaseAddress(imageBuffer,0); | |
size_t height = CVPixelBufferGetHeight(imageBuffer); | |
size_t width = CVPixelBufferGetWidth(imageBuffer); | |
size_t bytesPerRow = CVPixelBufferGetBytesPerRow(imageBuffer); | |
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. | |
const NSUInteger bytesPerPixel = 4; | |
vImage_Buffer srcBuff = {sourceData, height, width, bytesPerRow}; | |
// Create dest buffer | |
CGFloat aspectRatio = (CGFloat)width / (CGFloat)height; | |
CGSize fitSize = CGSizeMake(kMaximumSmallFrameHeight * aspectRatio, kMaximumSmallFrameHeight); | |
const NSUInteger scale = (NSUInteger)[[UIScreen mainScreen] scale]; | |
const NSUInteger dstWidth = (NSUInteger)fitSize.width * scale; | |
const NSUInteger dstHeight = (NSUInteger)fitSize.height * scale; | |
const NSUInteger dstBytesPerRow = bytesPerPixel * dstWidth; | |
uint8_t* dstData = (uint8_t*)calloc(dstHeight * dstWidth * bytesPerPixel, sizeof(uint8_t)); | |
vImage_Buffer dstBuffer = { | |
.data = dstData, | |
.height = dstHeight, | |
.width = dstWidth, | |
.rowBytes = dstBytesPerRow | |
}; | |
// Scale | |
vImage_Error ret = vImageScale_ARGB8888(&srcBuff, &dstBuffer, NULL, kvImageHighQualityResampling); | |
if (ret != kvImageNoError) | |
{ | |
free(dstData); | |
} | |
// Create CGImage from vImage_Buffer | |
vImage_CGImageFormat format = { | |
.bitsPerComponent = 8, | |
.bitsPerPixel = 32, | |
.colorSpace = NULL, | |
.bitmapInfo = (CGBitmapInfo)kCGImageAlphaFirst, | |
.version = 0, | |
.decode = NULL, | |
.renderingIntent = kCGRenderingIntentDefault, | |
}; | |
CGImageRef destRef = vImageCreateCGImageFromBuffer(&dstBuffer, &format, NULL, NULL, kvImageNoFlags, &ret); | |
free(dstData); | |
// Create UIImage | |
UIImage* smallFrame = [[UIImage alloc] initWithCGImage:destRef]; | |
// Free up the remaining memory | |
CGImageRelease(destRef); | |
CVPixelBufferUnlockBaseAddress(imageBuffer, 0); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment