Skip to content

Instantly share code, notes, and snippets.

@podkovyrin
Last active November 25, 2022 10:52
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 5 You must be signed in to fork a gist
  • Save podkovyrin/d4f0bdb761139bfed26fef74e6471d0d to your computer and use it in GitHub Desktop.
Save podkovyrin/d4f0bdb761139bfed26fef74e6471d0d to your computer and use it in GitHub Desktop.
CMSampleBufferRef to vImage and resize
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);
@hunter858
Copy link

Object-C

@nickdimiCiQ
Copy link

What "kMaximumSmallFrameHeight" stands for?

@podkovyrin
Copy link
Author

@nickdimiCiQ the height of the image to scale to, for instance, 640px

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment