Last active
November 25, 2022 10:52
-
-
Save podkovyrin/d4f0bdb761139bfed26fef74e6471d0d 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); |
What "kMaximumSmallFrameHeight" stands for?
@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
Object-C