我试图使用以下代码创建一些复合UIImage对象:
someImageView.image = [ImageMaker coolImage];
ImageMaker:
- (UIImage*)coolImage {
UIView *composite = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 400, 400)];
UIImageView *imgView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"coolImage"]]; //This is a valid image - can be viewed when debugger stops here
[composite addSubview:imgView];
UIView *snapshotView = [composite snapshotViewAfterScreenUpdates:YES];
//at this point snapshotView is just a blank image
UIImage *img = [self imageFromView:snapshotView];
return img;
}
- (UIImage *)imageFromView:(UIView *)view
{
UIGraphicsBeginImageContextWithOptions(view.bounds.size, YES, 0.0);
[view drawViewHierarchyInRect:view.bounds afterScreenUpdates:NO];
UIImage * img = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return img;
}
我刚回来一张黑色的空白图片。我该如何解决?
答案 0 :(得分:7)
为YES
提供-snapshotViewAfterScreenUpdates:
意味着它需要返回runloop才能实际绘制图像。如果您提供NO
,它会立即尝试,但如果您的视图在屏幕外或者尚未显示在屏幕上,则快照将为空。
要可靠地获取图像:
- (void)withCoolImage:(void (^)(UIImage *))block {
UIView *composite = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 400, 400)];
UIImageView *imgView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"coolImage"]]; //This is a valid image - can be viewed when debugger stops here
[composite addSubview:imgView];
UIView *snapshotView = [composite snapshotViewAfterScreenUpdates:YES];
// give it a chance to update the screen…
dispatch_async(dispatch_get_main_queue(), ^
{
// … and now it'll be a valid snapshot in here
if(block)
{
block([self imageFromView:snapshotView]);
}
});
}
您可以这样使用它:
[someObject withCoolImage:^(UIImage *image){
[self doSomethingWithImage:image];
}];
答案 1 :(得分:2)
必须将快照视图绘制到屏幕上,以使快照视图不为空白。在您的情况下,复合视图必须具有用于绘图才能工作的超级视图。
但是,您不应该使用快照API进行此类操作。仅为创建图像而创建视图层次结构效率非常低。相反,使用Core Graphics API设置位图图像上下文,执行绘图并使用UIGraphicsGetImageFromCurrentImageContext()
获取结果。
答案 2 :(得分:1)
它只渲染黑色矩形的原因是因为您正在绘制快照视图的视图层次结构,这是不存在的。
要使其正常工作,您应该将composite
作为参数传递,如下所示:
- (UIImage*)coolImage {
UIView *composite = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 400, 400)];
UIImageView *imgView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"coolImage"]]
[composite addSubview:imgView];
UIImage *img = [self imageFromView:composite];
// Uncomment if you don't want composite to have imgView as its subview
// [imgView removeFromSuperview];
return img;
}