近期需要在 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;
參考資料:
- http://www.touch-code-magazine.com/ios5-saving-photos-in-custom-photo-album-category-for-download/
- http://developer.apple.com/library/ios/#documentation/UIKit/Reference/UIKitFunctionReference/Reference/reference.html
- http://albert-oma.blogspot.com/2013/05/ffmpeg-save-streaming-data-as-image-in.html