iOS 图片转yuv与CVPixelBufferRef转image
图片转yuv
//很奇怪不知道为啥红色和橙色等亮色都成了蓝色... 难道说只能用libyuv去转?
- (CVPixelBufferRef)convertYUVWithImage:(UIImage *)image{
CGImageRef imageRef = image.CGImage;
CGDataProviderRef provider = CGImageGetDataProvider(imageRef);
CFDataRef pixelData = CGDataProviderCopyData(provider);
const unsigned char *data = CFDataGetBytePtr(pixelData);
size_t bitsPerPixel = CGImageGetBitsPerPixel(imageRef);
size_t bitsPerComponent = CGImageGetBitsPerComponent(imageRef);
size_t frameWidth = CGImageGetWidth(imageRef);
size_t frameHeight = CGImageGetHeight(imageRef);
size_t bytesPerRow = CGImageGetBytesPerRow(imageRef);
// NSLog(@"bytesPerRow:%lu ==:%lu",bytesPerRow,bytesPerRow/4);
CFRelease(pixelData);
NSDictionary *options = @{(id)kCVPixelBufferIOSurfacePropertiesKey : @{}};
CVPixelBufferRef pixelBuffer = NULL;
CVReturn status = CVPixelBufferCreate(kCFAllocatorDefault,
frameWidth,
frameHeight,
kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange,
(__bridge CFDictionaryRef)(options),
&pixelBuffer);
NSParameterAssert(status == kCVReturnSuccess && pixelBuffer != NULL);
CVPixelBufferLockBaseAddress(pixelBuffer, 0);
size_t width = CVPixelBufferGetWidth(pixelBuffer);
size_t height = CVPixelBufferGetHeight(pixelBuffer);
size_t wh = width * height;
// size_t bpr = CVPixelBufferGetBytesPerRow(pixelBuffer);
// size_t size = CVPixelBufferGetDataSize(pixelBuffer);
// size_t count = CVPixelBufferGetPlaneCount(pixelBuffer);
//plane0
size_t width0 = CVPixelBufferGetWidthOfPlane(pixelBuffer, 0);
size_t height0 = CVPixelBufferGetHeightOfPlane(pixelBuffer, 0);
size_t bpr0 = CVPixelBufferGetBytesPerRowOfPlane(pixelBuffer, 0);
//plane1
// size_t width1 = CVPixelBufferGetWidthOfPlane(pixelBuffer, 1);
size_t height1 = CVPixelBufferGetHeightOfPlane(pixelBuffer, 1);
size_t bpr1 = CVPixelBufferGetBytesPerRowOfPlane(pixelBuffer, 1);
unsigned char *bufY = malloc(wh);
unsigned char *bufUV = malloc(wh/2);
size_t offset,p;
int r,g,b,y,u,v;
int a=255;
for (int row = 0; row < height; ++row) {
for (int col = 0; col < width; ++col) {
//
offset = ((width * row) + col);
p = offset*4;
//
r = data[p + 0];
g = data[p + 1];
b = data[p + 2];
a = data[p + 3];
//yuv
y = 0.299*r + 0.587*g + 0.114*b;
u = -0.1687*r - 0.3313*g + 0.5*b + 128;
v = 0.5*r - 0.4187*g - 0.0813*b + 128;
//
bufY[offset] = y;
bufUV[(row/2)*width + (col/2)*2] = u;
bufUV[(row/2)*width + (col/2)*2 + 1] = v;
}
}
uint8_t *yPlane = CVPixelBufferGetBaseAddressOfPlane(pixelBuffer, 0);
memset(yPlane, 0x80, height0 * bpr0);
for (int row=0; row<height0; ++row) {
memcpy(yPlane + row*bpr0, bufY + row*width0, width0);
}
uint8_t *uvPlane = CVPixelBufferGetBaseAddressOfPlane(pixelBuffer, 1);
memset(uvPlane, 0x80, height1 * bpr1);
for (int row=0; row<height1; ++row) {
memcpy(uvPlane + row*bpr1, bufUV + row*width, width);
}
CVPixelBufferUnlockBaseAddress(pixelBuffer, 0);
free(bufY);
free(bufUV);
return pixelBuffer;
}
CVPixelBufferRef转image
- (UIImage *)bufferConvertToImage:(CVPixelBufferRef)pixelBuffer {
CIImage *cImage = [CIImage imageWithCVPixelBuffer:pixelBuffer];
CIContext *context = [CIContext contextWithOptions:nil];
CGImageRef videoImage = [context
createCGImage:cImage
fromRect:CGRectMake(0, 0, CVPixelBufferGetWidth(pixelBuffer), CVPixelBufferGetHeight(pixelBuffer))];
UIImage *uiImage = [UIImage imageWithCGImage:videoImage];
CGImageRelease(videoImage);
return uiImage;
}
未经作者授权,禁止转载
本文来自博客园,作者:CoderWGB,转载请注明原文链接:https://www.cnblogs.com/wgb1234/articles/16916360.html
THE END

浙公网安备 33010602011771号