简体   繁体   English

从CGBitmapContext创建CGImage并添加到UIImageView

[英]Create CGImage From CGBitmapContext and Add to UIImageView

I am trying to create a snapshot of a UICollectionViewCell by creating a CGBitMapContext. 我正在尝试通过创建CGBitMapContext创建UICollectionViewCell的快照。 I am not entirely clear on how to do this or how to use the associated classes, but after a bit of research, I have written the following method which is called from inside my UICollectionViewCell subclass: 我尚不清楚如何执行此操作或如何使用关联的类,但是经过一番研究,我编写了以下方法,该方法是从UICollectionViewCell子类内部调用的:

- (void)snapShotOfCell
{
    float scaleFactor = [[UIScreen mainScreen] scale];
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
    CGContextRef context = CGBitmapContextCreate(NULL, self.frame.size.width * scaleFactor, self.frame.size.height * scaleFactor, 8, self.frame.size.width * scaleFactor * 4, colorSpace, kCGImageAlphaPremultipliedFirst);

    CGImageRef image = CGBitmapContextCreateImage(context);
    UIImage *snapShot = [[UIImage alloc]initWithCGImage:image];

    UIImageView *imageView = [[UIImageView alloc]initWithFrame:self.frame];
    imageView.image = snapShot;
    imageView.opaque = YES;
    [self addSubview:imageView];

     CGImageRelease(image);
     CGContextRelease(context);
     CGColorSpaceRelease(colorSpace);
}

The result is that the image does not appear. 结果是该图像没有出现。 Upon debugging, I can determine that I have a valid (non nil) context, CGImage, UIImage and UIImageView, but nothing appears onscreen. 调试后,我可以确定我具有有效的(非nil)上下文,CGImage,UIImage和UIImageView,但是屏幕上没有任何显示。 Can someone tell me what I am missing? 有人可以告诉我我想念什么吗?

You can add this as a category to UIView and it will be accessible for any view 您可以将其添加为UIView的类别,任何视图均可访问

- (UIImage*) snapshot
{
    UIGraphicsBeginImageContextWithOptions(self.frame.size, YES /*opaque*/, 0 /*auto scale*/);
    [self.layer renderInContext:UIGraphicsGetCurrentContext()];
    UIImage* image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return image;
}

Then you just need to do [self addSubview:[[UIImageView alloc] initWithImage:self.snapshot]] from you cell object. 然后,您只需要从单元格对象执行[self addSubview:[[UIImageView alloc] initWithImage:self.snapshot]]

[EDIT] [编辑]

Providing the need for asynchronous rendering (totally understandable) this can be achieved using dispatch queues. 如果需要异步渲染(完全可以理解),则可以使用调度队列来实现。 I think this would work: 我认为这会起作用:

typedef void(^ImageOutBlock)(UIImage* image);

- (void) snapshotAsync:(ImageOutBlock)block
{
    CGFloat scale = [[UIScreen mainScreen] scale];
    CALayer* layer = self.layer;
    CGRect frame = self.frame;
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^() {
        CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
        CGContextRef context = CGBitmapContextCreate(NULL, frame.size.width * scaleFactor, frame.size.height * scaleFactor, 8, frame.size.width * scaleFactor * 4, colorSpace, kCGImageAlphaPremultipliedFirst);
        UIGraphicsBeginImageContextWithOptions(frame.size, YES /*opaque*/, scale);
        [layer renderInContext:UIGraphicsGetCurrentContext()];
        UIImage* image = UIGraphicsGetImageFromCurrentImageContext();
        UIGraphicsEndImageContext();
        CGContextRelease(context);
        CGColorSpaceRelease(colorSpace);
        dispatch_async(dispatch_get_main_queue(), ^() {
            block(image);
        });
    });
}

[EDIT] [编辑]

- (void) execute
{
    __weak typeof(self) weakSelf = self;
    [self snapshotAsync:^(UIImage* image) { 
        [weakSelf addSubview:[[UIImageView alloc] initWithImage:image]] 
    }];
}

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

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