2013年5月22日 星期三

FFMPEG -- Save streaming data as image in iOS

近期需要在 iPhone 的串流應用程式加上擷取圖片的功能,將自己的實作經驗作一整理。

Step 1. 使用FFMPEG取得串流內的影像資料,並進行解碼
av_read_frame(pFormatCtx, &packet); avcodec_decode_video2(videoCodecCtx, DecodedFrame, &frameFinished, & packet);



Step 2. 將影像轉成 iOS 定義的 UIImage
先將 YUV格式的 AVFrame 轉換為 RGB格式的 AVPicture
img_convert_ctx = sws_getContext(pCodecCtx->width, pCodecCtx->height, pCodecCtx->pix_fmt, outputWidth, outputHeight, PIX_FMT_RGB24, sws_flags, NULL, NULL, NULL);
再將 AVPicture 轉換為 iOS 的 UIImage
-(UIImage *)imageFromAVPicture:(AVPicture)pict width:(int)width height:(int)height { CGBitmapInfo bitmapInfo = kCGBitmapByteOrderDefault; CFDataRef data = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, pict.data[0], pict.linesize[0]*height,kCFAllocatorNull); CGDataProviderRef provider = CGDataProviderCreateWithCFData(data); CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); CGImageRef cgImage = CGImageCreate(width, height, 8, 24, pict.linesize[0], colorSpace, bitmapInfo, provider, NULL, NO, kCGRenderingIntentDefault); CGColorSpaceRelease(colorSpace); UIImage *image = [UIImage imageWithCGImage:cgImage]; CGImageRelease(cgImage); CGDataProviderRelease(provider); CFRelease(data); return image; }


Step 3. 將 UIImage 存檔
這邊整理三種方法 
1. 將檔案存入指定的目錄 (PNG or JPEG)
[UIImageJPEGRepresentation(image, 1.0) writeToFile:jpgPath atomically:YES]; [UIImagePNGRepresentation(image) writeToFile:pngPath atomically:YES]; 
2. 將影像直接存入相簿 (JPEG)
void UIImageWriteToSavedPhotosAlbum ( UIImage *image, id completionTarget, SEL completionSelector, void *contextInfo );
3. 將檔案存入相簿中的特定群組
iOS預設並沒有提供此種功能。
因此可以參考 www.touch-code-magazine.com 的文章,使用下列客製化的API完成此功能。 
-(void)saveImage:(UIImage*)image toAlbum:(NSString*)albumName withCompletionBlock:(SaveImageCompletion)completionBlock;



參考資料: