5.将UIView转化为UIImage,并转化为data和base64
6.将视频一帧(CMSampleBufferRef)转换为UIImage
//给定角度旋转图片 -(UIImage *)image:(UIImage *)image rotation:(UIImageOrientation)orientation { long double rotate = 0.0; CGRect rect; float translateX = 0; float translateY = 0; float scaleX = 1.0; float scaleY = 1.0; switch (orientation) { case UIImageOrientationLeft: rotate = M_PI_2; rect = CGRectMake(0, 0, image.size.height, image.size.width); translateX = 0; translateY = -rect.size.width; scaleY = rect.size.width/rect.size.height; scaleX = rect.size.height/rect.size.width; break; case UIImageOrientationRight: rotate = 3 * M_PI_2; rect = CGRectMake(0, 0, image.size.height, image.size.width); translateX = -rect.size.height; translateY = 0; scaleY = rect.size.width/rect.size.height; scaleX = rect.size.height/rect.size.width; break; case UIImageOrientationDown: rotate = M_PI; rect = CGRectMake(0, 0, image.size.width, image.size.height); translateX = -rect.size.width; translateY = -rect.size.height; break; default: rotate = 0.0; rect = CGRectMake(0, 0, image.size.width, image.size.height); translateX = 0; translateY = 0; break; } UIGraphicsBeginImageContext(rect.size); CGContextRef context = UIGraphicsGetCurrentContext(); //做CTM变换 CGContextTranslateCTM(context, 0.0, rect.size.height); CGContextScaleCTM(context, 1.0, -1.0); CGContextRotateCTM(context, rotate); CGContextTranslateCTM(context, translateX, translateY); CGContextScaleCTM(context, scaleX, scaleY); //绘制图片 CGContextDrawImage(context, CGRectMake(0, 0, rect.size.width, rect.size.height), image.CGImage); UIImage *newPic = UIGraphicsGetImageFromCurrentImageContext(); return newPic; }
//按比例缩放,size 是你要把图显示到 多大区域 CGSizeMake(980, 560) -(UIImage *) imageCompressForSize:(UIImage *)sourceImage targetSize:(CGSize)size{ UIImage *newImage = nil; CGSize imageSize = sourceImage.size; CGFloat width = imageSize.width; CGFloat height = imageSize.height; CGFloat targetWidth = size.width; CGFloat targetHeight = size.height; CGFloat scaleFactor = 0.0; CGFloat scaledWidth = targetWidth; CGFloat scaledHeight = targetHeight; CGPoint thumbnailPoint = CGPointMake(0.0, 0.0); if(CGSizeEqualToSize(imageSize, size) == NO){ CGFloat widthFactor = targetWidth / width; CGFloat heightFactor = targetHeight / height; if(widthFactor > heightFactor){ scaleFactor = widthFactor; } else{ scaleFactor = heightFactor; } scaledWidth = width * scaleFactor; scaledHeight = height * scaleFactor; if(widthFactor > heightFactor){ thumbnailPoint.y = (targetHeight - scaledHeight) * 0.5; }else if(widthFactor < heightFactor){ thumbnailPoint.x = (targetWidth - scaledWidth) * 0.5; } } UIGraphicsBeginImageContext(size); CGRect thumbnailRect = CGRectZero; thumbnailRect.origin = thumbnailPoint; thumbnailRect.size.width = scaledWidth; thumbnailRect.size.height = scaledHeight; [sourceImage drawInRect:thumbnailRect]; newImage = UIGraphicsGetImageFromCurrentImageContext(); if(newImage == nil){ NSLog(@"scale image fail"); } UIGraphicsEndImageContext(); return newImage; }
CGRect rect=CGRectMake(0, 0, 100, 100); //截取图片指定区域 img=[UIImage imageWithCGImage:CGImageCreateWithImageInRect(img.CGImage, rect)];
void ProviderReleaseData (void *info, const void *data, size_t size) { free((void*)data); } //图片颜色变换处理 - (UIImage*) imageBlackToTransparent:(UIImage*) image { // 分配内存 const int imageWidth = image.size.width; const int imageHeight = image.size.height; size_t bytesPerRow = imageWidth * 4; uint32_t* rgbImageBuf = (uint32_t*)malloc(bytesPerRow * imageHeight); // 创建context CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); CGContextRef context = CGBitmapContextCreate(rgbImageBuf, imageWidth, imageHeight, 8, bytesPerRow, colorSpace, kCGBitmapByteOrder32Little | kCGImageAlphaNoneSkipLast); CGContextDrawImage(context, CGRectMake(0, 0, imageWidth, imageHeight), image.CGImage); // 遍历像素 int pixelNum = imageWidth * imageHeight; uint32_t* pCurPtr = rgbImageBuf; for (int i = 0; i < pixelNum; i++, pCurPtr++) { if ((*pCurPtr & 0xFFFFFF00) == 0xffffff00) // 将白色变成透明 // if ((*pCurPtr & 0x65815A00) == 0x65815a00) // 将背景变成透明 { uint8_t* ptr = (uint8_t*)pCurPtr; ptr[0] = 0; }else{//其他颜色修改 // 改成下面RGB值的代码,会将图片转成想要的颜色 uint8_t* ptr = (uint8_t*)pCurPtr; //rgb 值0~255 ptr[3] = 226;//red ptr[2] = 89;//green ptr[1] = 72;//blue } } // 将内存转成image CGDataProviderRef dataProvider = CGDataProviderCreateWithData(NULL, rgbImageBuf, bytesPerRow * imageHeight, ProviderReleaseData); CGImageRef imageRef = CGImageCreate(imageWidth, imageHeight, 8, 32, bytesPerRow, colorSpace, kCGImageAlphaLast | kCGBitmapByteOrder32Little, dataProvider, NULL, true, kCGRenderingIntentDefault); CGDataProviderRelease(dataProvider); UIImage* resultUIImage = [UIImage imageWithCGImage:imageRef]; // 释放 CGImageRelease(imageRef); CGContextRelease(context); CGColorSpaceRelease(colorSpace); return resultUIImage; }
将UIView转化为UIImage,并转化为data和base64
//将UIView转化为UIImage -(UIImage *)createImageFromView:(UIView *)view{ //屏幕密度 CGFloat scale=[UIScreen mainScreen].scale; //开始绘图,区域大小,半透明效果,屏幕密度 UIGraphicsBeginImageContextWithOptions(self.view.frame.size, NO, scale); [view.layer renderInContext:UIGraphicsGetCurrentContext()]; //开始生成图片 UIImage *image=UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); return image; } //确定签名事件 -(void)okAction:(UIButton *)sender{ [self.touchView.cleanBtn removeFromSuperview]; //将有签名的视图转化为img并获取data UIImage *img=[self createImageFromView:self.touchView]; NSData *data=UIImageJPEGRepresentation(img, 80.0f); //将data转化为base64字符串 NSString *base64Str=[data base64EncodedStringWithOptions:NSDataBase64Encoding64CharacterLineLength]; NSString *utf8Str=[NSString stringWithUTF8String:[base64Str UTF8String]]; //base64转UIImage NSData *dataUtf8=[[NSData alloc] initWithBase64EncodedString:utf8Str options:NSDataBase64DecodingIgnoreUnknownCharacters]; UIImage *base64Image=[UIImage imageWithData:dataUtf8]; }
将视频一帧(CMSampleBufferRef)转换为UIImage
//用AVFoundation捕捉视频帧,很多时候需要把某一帧转换成UIImage,用此函数: - (UIImage *) imageFromSampleBuffer:(CMSampleBufferRef) sampleBuffer { // 为媒体数据设置一个CMSampleBuffer的Core Video图像缓存对象 CVImageBufferRef imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer); // 锁定pixel buffer的基地址 CVPixelBufferLockBaseAddress(imageBuffer, 0); // 得到pixel buffer的基地址 void *baseAddress = CVPixelBufferGetBaseAddress(imageBuffer); // 得到pixel buffer的行字节数 size_t bytesPerRow = CVPixelBufferGetBytesPerRow(imageBuffer); // 得到pixel buffer的宽和高 size_t width = CVPixelBufferGetWidth(imageBuffer); size_t height = CVPixelBufferGetHeight(imageBuffer); // 创建一个依赖于设备的RGB颜色空间 CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); // 用抽样缓存的数据创建一个位图格式的图形上下文(graphics context)对象 CGContextRef context = CGBitmapContextCreate(baseAddress, width, height, 8,bytesPerRow, colorSpace, kCGBitmapByteOrder32Little | kCGImageAlphaPremultipliedFirst); // 根据这个位图context中的像素数据创建一个Quartz image对象 CGImageRef quartzImage = CGBitmapContextCreateImage(context); // 解锁pixel buffer CVPixelBufferUnlockBaseAddress(imageBuffer,0); // 释放context和颜色空间 CGContextRelease(context); CGColorSpaceRelease(colorSpace); // 用Quartz image创建一个UIImage对象image UIImage *image = [UIImage imageWithCGImage:quartzImage]; // 释放Quartz image对象 CGImageRelease(quartzImage); return (image); }
当然,先不要急,因为捕捉到得帧是YUV颜色通道的,这种颜色通道无法通过以上函数转换,RGBA颜色通道才可以成功转换,所以,先需要把视频帧的输出格式设置一下:
[videoOutput setVideoSettings:[NSDictionary dictionaryWithObject:[NSNumber numberWithInt:kCVPixelFormatType_32BGRA] forKey:(id)kCVPixelBufferPixelFormatTypeKey]];