2013-01-11 20 views
10

ViewでAVPlayerLayerを使用してビデオを再生しています。私は画像をビューに変換する必要があります、私は試しましたUIViewレイヤーをUIImageに変換する

[myview.layer renderInContext:context]; 

しかし、これは黒い画像だけを与えます。私はその時のビデオを使ってそのビューを画像に変換したいと思っています。この変換は同時に0.05s起こる。

私はAVAssetImageGeneratorを試しました。これは資産を使って私に正しいイメージを与えます。しかし、それは私のアプリケーション上でいくつかのパフォーマンスの問題を引き起こす少し時間がかかります。特定のCMTimeのビデオをイメージに変換するプロセスを減らす方法を教えてもらえますか?

以下は私のコーディングです。

- (UIImage *)currentItemScreenShot 
{ 
    AVPlayer *abovePlayer = [objVC player]; 
    if(imageGenerator == nil) 
    { 
     AVAsset *asset = [[[objVC player] currentItem] asset]; 
     imageGenerator = [[AVAssetImageGenerator alloc] initWithAsset:asset]; 
    } 

    CMTime time = [[abovePlayer currentItem] currentTime]; 
    if ([imageGenerator respondsToSelector:@selector(setRequestedTimeToleranceBefore:)] && [imageGenerator respondsToSelector:@selector(setRequestedTimeToleranceAfter:)]) { 
     [imageGenerator setRequestedTimeToleranceBefore:kCMTimeZero]; 
     [imageGenerator setRequestedTimeToleranceAfter:kCMTimeZero]; 
    } 

    CGImageRef imgRef = [imageGenerator copyCGImageAtTime:time 
               actualTime:NULL 
                error:NULL]; 
    if (imgRef == nil) { 
     if ([imageGenerator respondsToSelector:@selector(setRequestedTimeToleranceBefore:)] && [imageGenerator respondsToSelector:@selector(setRequestedTimeToleranceAfter:)]) { 
      [imageGenerator setRequestedTimeToleranceBefore:kCMTimePositiveInfinity]; 
      [imageGenerator setRequestedTimeToleranceAfter:kCMTimePositiveInfinity]; 
     } 
     imgRef = [imageGenerator copyCGImageAtTime:time actualTime:NULL error:NULL]; 
    } 
    UIImage *image = [UIImage imageWithCGImage:imgRef]; 
    CGImageRelease(imgRef); 

    image = [self reverseImageByScalingToSize:image.size :image]; 
    return image; 
} 
+0

私はその上AVPlayerLayerを使用している私の場合は、このリンクhttp://stackoverflow.com/questions/14049796/howe-to-capture-uiview-top-uiview/14049828#14049862 –

+0

から私の答えを参照してください表示、私はそのビューでビデオフレームが必要 – Ganesh

+0

http://stackoverflow.com/q/5388226/1378447 –

答えて

2

あなたは次のようにドキュメントDiretoryの画像のように、あなたのUIViewを保存することができます:

-(IBAction)ViewTOimage:(id)sender 
{ 


    UIGraphicsBeginImageContext(self.view.bounds.size); //instad of self.view you can set your view IBOutlet name 
    [self.view.layer renderInContext:UIGraphicsGetCurrentContext()]; 
    UIImage *saveImage = UIGraphicsGetImageFromCurrentImageContext(); 

    UIGraphicsEndImageContext(); 
    NSData *imageData = UIImagePNGRepresentation(saveImage); 
    NSFileManager *fileMan = [NSFileManager defaultManager]; 

    NSString *fileName = [NSString stringWithFormat:@"%d.png",1]; 
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 
    NSString *documentsDirectory = [paths objectAtIndex:0]; 
    NSString *pdfFileName = [documentsDirectory stringByAppendingPathComponent:fileName]; 
    [fileMan createFileAtPath:pdfFileName contents:imageData attributes:nil]; 



} 
+0

私もこれを試しました。そのビューのAVPlayerLayerのために、私は空白の画像しか表示しません:( – Ganesh

+0

あなたのビューはself.viewか他のものですか?あなたのビュー名は何ですか?IBOutlat ..? –

+0

プレーヤービューはIBOutletです。 – Ganesh

3

コードの下にしてみてください。それは私にとって完璧に働いています。

UIKit Function Referenceを参照してください。

+ (UIImage *) imageWithView:(UIView *)view 
{ 
    UIGraphicsBeginImageContextWithOptions(view.bounds.size, view.opaque, 0.0); 
    [view.layer renderInContext:UIGraphicsGetCurrentContext()]; 

    UIImage * img = UIGraphicsGetImageFromCurrentImageContext(); 

    UIGraphicsEndImageContext(); 

    return img; 
} 

また、thisを試してください。

+0

私は同じことを試みましたが、imgは黒で空白です。あなたの場合は、あなたのビューでavplayerlayerを使用しましたか? – Ganesh

2

このコード....

- (UIImage *)captureView { 

//hide controls if needed 
    CGRect rect = [self.view bounds]; 

    UIGraphicsBeginImageContext(rect.size); 
    CGContextRef context = UIGraphicsGetCurrentContext(); 
    [self.view.layer renderInContext:context]; 
    UIImage *img = UIGraphicsGetImageFromCurrentImageContext(); 
    UIGraphicsEndImageContext(); 
    return img; 

} 

はまた、私のこの回答を参照してください....ユーザーが現在のビューのスクリーンショットをキャプチャし、共有したり、このイメージを保存したい場合に便利です My Answer

UPDATE:

AVPlayerItem *item = [AVPlayerItem playerItemWithURL:yourURL]; 
AVPlayer *player = [AVPlayer playerWithPlayerItem:pItem]; 

//observe 'status' 
[playerItem addObserver:self forKeyPath:@"status" options:0 context:nil]; 

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object 
         change:(NSDictionary *)change context:(void *)context 
{ 
    if ([keyPath isEqualToString:@"status"]) { 
     AVPlayerItem *item = (AVPlayerItem *)object; 
     if (item.status == AVPlayerItemStatusReadyToPlay) { 
      AVURLAsset *asset = (AVURLAsset *)item.asset; 
      AVAssetImageGenerator *imageGenerator = [[AVAssetImageGenerator alloc] initWithAsset:asset]; 
      CGImageRef thumb = [imageGenerator copyCGImageAtTime:CMTimeMakeWithSeconds(10.0, 1.0) 
                 actualTime:NULL 
                  error:NULL]; 
     } 
    } 
} 
+0

このビューでAVPlayerLayerを使用しています。ビューを画像に変換しようとすると、黒い画像が表示されます。そのビューのAVPlayerLayerで試しましたか? – Ganesh

+0

上記のコードを試してください??? –

+0

はい私はしましたが、使用していません – Ganesh

2
-(UIImage *)imagefromview { 
    UIGraphicsBeginImageContext(view.frame.size); 
    [[self imageFromView:view] drawInRect:view.frame]; 
    [self.view.layer renderInContext:UIGraphicsGetCurrentContext()]; 
    UIImage *resultingImage = UIGraphicsGetImageFromCurrentImageContext(); 
    UIGraphicsEndImageContext(); 
    return resultingImage; 
} 
5

MPMoviePlayerContro llerは、ムービーの特定のポイントでムービーからイメージを取得することを容易にします。

- (UIImage*)imageFromVideoAtPath:(NSString *)path atTime:(NSTimeInterval)time { 
    NSURL *videoURL = [NSURL fileURLWithPath:path]; 
    MPMoviePlayerController *moviePlayer = [[MPMoviePlayerController alloc] initWithContentURL:videoURL]; 
    [moviePlayer prepareToPlay]; 
    UIImage *thumbnail = [moviePlayer thumbnailImageAtTime:time timeOption:MPMovieTimeOptionNearestKeyFrame]; 
    [moviePlayer stop]; 
    return thumbnail; 
} 

これをビデオのパスで呼び出すと、画像を取得したいときに呼び出します。

2

私は以下のコードを使ってビデオを再生していますが、これはあなたにも役立ちますか?見てみて、あなたのコードで調整してみてください。

#import <AVFoundation/AVFoundation.h> 

@property (nonatomic,retain) AVCaptureStillImageOutput * resultImageOutput; 

- (UIImage*)stillImageFromVideo 
{ 
    AVCaptureConnection *videoConnection = nil; 
    for (AVCaptureConnection *connection in [[self resultImageOutput] connections]) { 
     for (AVCaptureInputPort *port in [connection inputPorts]) { 
      if ([[port mediaType] isEqual:AVMediaTypeVideo]) { 
       videoConnection = connection; 
       break; 
      } 
     } 
     if (videoConnection) { 
      break; 
     } 
    } 

    [[self resultImageOutput] captureStillImageAsynchronouslyFromConnection:videoConnection 
    completionHandler:^(CMSampleBufferRef imageSampleBuffer, NSError *error) { 
     CFDictionaryRef exifAttachments = CMGetAttachment(imageSampleBuffer, 
    kCGImagePropertyExifDictionary, NULL); 

     NSData *imageData = [AVCaptureStillImageOutput jpegStillImageNSDataRepresentation:imageSampleBuffer];  
     UIImage *image = [[UIImage alloc] initWithData:imageData]; 
     return image; 
    } 
} 
2

スクリーンショットを撮り、クリップしてみてください。それ以外の場合は、ビューとすべてのサブビューを再帰的にレンダリングする必要があります。

-(UIImage *)videoScreenCap:(CGRect)cropRect{ 
if ([[UIScreen mainScreen] respondsToSelector:@selector(scale)]) 
    UIGraphicsBeginImageContextWithOptions(self.window.bounds.size, NO, [UIScreen mainScreen].scale); 
else 
    UIGraphicsBeginImageContext(self.window.bounds.size); 
    [self.window.layer renderInContext:UIGraphicsGetCurrentContext()]; 
    UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); 
    UIGraphicsEndImageContext(); 
    NSData * data = UIImagePNGRepresentation(image); 
    [data writeToFile:@"foo.png" atomically:YES]; 
CGImageRef imageRef = CGImageCreateWithImageInRect([largeImage CGImage], cropRect); 
UIImage * img = [UIImage imageWithCGImage:imageRef]; 
CGImageRelease(imageRef); 
return img; 
} 
+0

私はすべてのウィンドウでキャプチャしたくありません。私はちょうどSublayerとしてAVPlayerLayerを含む特定のViewをキャプチャする必要があります。私がcontextrefでview.layerをレンダリングするとき、ビデオスクリーンは黒です。 – Ganesh

関連する問題