I use the following to convert camera image data to UIImage. To save time and memory, I would like to crop the image data before turning it into a UIImage.
Ideally, I go into cropRect and return the trimmed UIImage. However, since the camera output may be different in size, based on whether I use a preliminary set of photos or videos, I probably don’t know what sizes to use for cropRect. I could use a cropRect similar to a focus or exposure point, which uses CGPoint between (0,0) and (1,1) and similarly performs a CGSizeof cropRect. Or I can get the sampleBuffer dimensions before I call the following, and go to the appropriate cropRect value. I would like advice on what I should use.
I would also like to know what is the best way to crop so as not to create the whole UIImage and then crop it. As a rule, I am only interested in 10-20% of the pixels. I guess I need to iterate over the pixels and start copying cropRect to another pixel buffer until I have all the pixels that I want.
And keep in mind that there is a possible rotation in accordance with orientation.
+ (UIImage *) imageFromSampleBuffer:(CMSampleBufferRef) sampleBuffer orientation:(UIImageOrientation) orientation
{
CVImageBufferRef imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer);
CVPixelBufferLockBaseAddress(imageBuffer, 0);
void *baseAddress = CVPixelBufferGetBaseAddress(imageBuffer);
size_t bytesPerRow = CVPixelBufferGetBytesPerRow(imageBuffer);
size_t width = CVPixelBufferGetWidth(imageBuffer);
size_t height = CVPixelBufferGetHeight(imageBuffer);
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGContextRef context = CGBitmapContextCreate(baseAddress, width, height, 8,
bytesPerRow, colorSpace, kCGBitmapByteOrder32Little | kCGImageAlphaPremultipliedFirst);
CGImageRef quartzImage = CGBitmapContextCreateImage(context);
CVPixelBufferUnlockBaseAddress(imageBuffer,0);
CGContextRelease(context);
CGColorSpaceRelease(colorSpace);
UIImage *image = [UIImage imageWithCGImage:quartzImage scale:(CGFloat)1.0 orientation:orientation];
CGImageRelease(quartzImage);
return (image);
}
In short:
- Should I pass in cropRect, which indicates a line between (0,0,0,0) and (1,1,1,1), or should I pass in cropRect, which indicates exact pixel locations, such as (50,50,100,100) ?
- What is the best way to crop a pixel buffer?
source
share