简体   繁体   English

将UIView层转换为UIImage

[英]Convert UIView Layer to UIImage

I'm playing Video using AVPlayerLayer in a View. 我在视图中使用AVPlayerLayer播放视频。 I need to convert View to Image, I tried 我需要将View转换为Image,我试过了

[myview.layer renderInContext:context];

but this gives only black image. 但这只给出了黑色图像。 I wanna convert that view into image with video on that time. 我想在那个时候用视频将那个视图转换成图像。 This conversion will occur simultaneously 0.05s. 此转换将同时发生0.05秒。

I tried with AVAssetImageGenerator. 我试过AVAssetImageGenerator。 Which gives me the right image using Asset. 这给了我使用Asset的正确图像。 But it taking little more time which makes some performance issue on my application. 但它花费的时间更多,这使我的应用程序出现性能问题。 Can any one help me how to reduce the process of converting video to image for particular CMTime. 任何人都可以帮助我减少如何减少特定CMTime的视频转换为图像的过程。

Below are my coding. 以下是我的编码。

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

The MPMoviePlayerController makes it easy to get a image from a movie at a certain point in the movie. 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;
}

Just call this with the path of the video, and at the time you want to get the image. 只需用视频的路径调用它,然后在想要获取图像时。

Please try below code. 请尝试下面的代码。 It is working perfectly for me. 它对我来说非常合适。

And refer UIKit Function Reference . 并参考UIKit功能参考

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

    UIImage * img = UIGraphicsGetImageFromCurrentImageContext();

    UIGraphicsEndImageContext();

    return img;
}

Also try this . 也试试这个

you can save your UIView as Image in Document Diretory like: 你可以将你的UIView保存为Document Diretory中的Image,如:

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



}

This Code Useful when user want to capture current view ScreenShot and share or save this image.... 此代码在用户想要捕获当前视图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;

}

See my this Answer Also.... 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];
        }
    }   
}
-(UIImage *)imagefromview {
    UIGraphicsBeginImageContext(view.frame.size);
    [[self imageFromView:view] drawInRect:view.frame];
    [self.view.layer renderInContext:UIGraphicsGetCurrentContext()];
    UIImage *resultingImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return resultingImage;
}

I one of the project i used the below code to take an image from playing video might this help you too... take a look and try adjusting the code with your's. 我使用下面的代码来拍摄视频中的图像的项目之一也可能对你有所帮助...看看并尝试用你的代码调整代码。

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

Try taking a screenshot and clipping. 尝试截屏和剪辑。 Otherwise you may have to render view and all its subviews recursively. 否则,您可能必须递归地呈现视图及其所有子视图。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM