2013-01-11 15 views
10

Sto riproducendo video usando AVPlayerLayer in una vista. Ho bisogno di convertire View to Image, ho provatoConverti UIView Layer in UIImage

[myview.layer renderInContext:context]; 

ma questo dà solo l'immagine nera. Voglio convertire quella vista in immagine con video in quel momento. Questa conversione avverrà simultaneamente a 0,05 s.

Ho provato con AVAssetImageGenerator. Che mi dà l'immagine giusta usando Asset. Ma ci vuole un po 'più di tempo, il che rende qualche problema di prestazioni sulla mia applicazione. Qualcuno può aiutarmi a ridurre il processo di conversione di video in immagine per particolari CMTime.

Di seguito sono riportati i miei codici.

- (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

Vedere la mia risposta da questo link http://stackoverflow.com/questions/14049796/howe-to-capture-uiview-top-uiview/14049828#14049862 –

+0

Nel mio caso sto usando AVPlayerLayer su quel Visualizza, ho bisogno del frame video su quella vista – Ganesh

+0

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

risposta

2

è possibile salvare l'UIView come immagine nel documento diretory come:

-(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

Ho provato anche questo. A causa di AVPlayerLayer su quella vista, mi danno solo le immagini vuote :( – Ganesh

+0

c'è la tua vista è self.view o altro? Qual è il tuo nome di visualizzazione..IBOutlat ..? –

+0

La vista giocatore è IBOutlet. È questo qualche problema? – Ganesh

3

Prova sotto il codice. Funziona perfettamente per me.

E fare riferimento a 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; 
} 

Prova anche this.

+0

Ho provato lo stesso ma l'img è nero e vuoto. Nel tuo caso hai usato avplayerlayer dal tuo punto di vista? – Ganesh

2

Questo codice utile quando l'utente desidera catturare vista corrente ScreenShot e condividere o salvare questa immagine ....

- (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; 

} 

Vedi il mio questa risposta anche .... 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

Sto usando AVPlayerLayer in questa vista. Se provo a convertire quella vista in immagine, mi dà l'immagine nera. Hai provato con AVPlayerLayer con quella vista? – Ganesh

+0

provi questo codice sopra ??? –

+0

Sì, ma non lo uso – 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

Il MPMoviePlayerContro Ller rende facile ottenere un'immagine da un film ad un certo punto del film.

- (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; 
} 

basta chiamare questo con il percorso del video, e al tempo che si desidera ottenere l'immagine.

2

Io uno dei progetti che ho usato il codice seguente per scattare una foto dal video potrebbe aiutare anche voi ... dare un'occhiata e provare a regolare il codice con i vostri.

#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

Provare a scattare uno screenshot e tagliare. Altrimenti potrebbe essere necessario eseguire il rendering della vista e di tutte le sue sottoview in modo ricorsivo.

-(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

Non voglio acquisire su tutta la finestra. Ho solo bisogno di catturare una vista particolare, che contiene AVPlayerLayer come sottolivello. Quando eseguo il rendering view.layer in uno schermo video contextref è nero. – Ganesh

Problemi correlati