11

我在视图中使用 AVPlayerLayer 播放视频。我需要将视图转换为图像,我试过了

[myview.layer renderInContext:context];

但这只会给出黑色图像。我想在那个时候将该视图转换为带有视频的图像。这种转换将同时发生 0.05 秒。

我尝试使用 AVAssetImageGenerator。这给了我使用 Asset 的正确图像。但这需要更多时间,这对我的应用程序造成了一些性能问题。任何人都可以帮助我如何减少特定 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;
}
4

7 回答 7

5

MPMoviePlayerController 可以很容易地从电影中的某个点获取图像。

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

只需用视频的路径调用它,然后在你想要获取图像的时候。

于 2013-01-20T17:36:29.577 回答
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;
}

也试试这个

于 2013-01-11T10:28:32.607 回答
2

当用户想要捕获当前视图 ScreenShot 并共享或保存此图像时,此代码很有用....

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

}

另见我的这个答案....我的答案

更新:

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];
        }
    }   
}
于 2013-01-11T10:33:22.590 回答
2
-(UIImage *)imagefromview {
    UIGraphicsBeginImageContext(view.frame.size);
    [[self imageFromView:view] drawInRect:view.frame];
    [self.view.layer renderInContext:UIGraphicsGetCurrentContext()];
    UIImage *resultingImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return resultingImage;
}
于 2013-01-11T11:28:12.760 回答
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;
}
于 2013-01-21T22:27:12.713 回答
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;  
    }
}
于 2013-01-21T07:49:59.023 回答
2

您可以将 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];



}
于 2013-01-11T10:16:43.710 回答