1

我有一个希望将其转换为 UIImage 的 EAGLView。我可以使用此处发布的解决方案来做到这一点:

如何从 EAGLView 获取 UIImage?

但是,如果在创建 EAGLView 和 UIImage 之间经过了一小段时间,我只能完成此操作。

这段代码创建了一个 EAGLView,然后是一个 UIImageView,它不起作用:

EAGLView *EAGLphoto = [[EAGLView alloc] initWithImage:photo.workAreaImage];

[theWorkArea.photoArea1 addSubview:EAGLphoto];

//I put a glfinish() here but it didn't help

UIImageView *photoView = [[UIImageView alloc] initWithImage:[self glToUIImage]];
//glToUIImage is taken from the link above

[theWorkArea.photoArea2 addSubview:photoView];

我假设 UIImageView 尝试在 EAGLView 完成创建之前创建。我试图在两者之间放置一个 glfinish() 但它什么也没做。当我运行代码时,EAGLView 显示正常,但 UIImageView 显示为黑色。

但是,上述代码的修改版本有效:

EAGLView *EAGLphoto = [[EAGLView alloc] initWithImage:photo.workAreaImage];

[theWorkArea.photoArea1 addSubview:EAGLphoto];

[self performSelector:@selector(getUIImage) withObject:nil afterDelay:0.1];

- (void)getUIImage {

    UIImageView *photoView = [[UIImageView alloc] initWithImage:[self glToUIImage]];
    //glToUIImage is taken from the link above

    [theWorkArea.photoArea2 addSubview:photoView];

}

我是否错误地使用了 glfinish() ?有比我的 hack 更好的方法吗?

4

1 回答 1

0

通常,当您对 UIKit 对象进行可见更改而不是立即更新时,它们只是标记自己以在将来进行这些更改,然后在您下次放弃主线程时将整个更改集作为批处理(通过返回到运行循环)。这不是实现中的错误或失败,它实际上通常是您隐含的期望,这就是您可以编写如下代码的原因:

view.frame = someNewFrame;
view.someOtherProperty = someOtherValue;

不用担心视图会在采用其他更改之前经常明显地采用新框架。通常,您希望您对视图所做的事情看起来是原子的。

有时您会遇到一种情况,就像您在这里遇到的情况一样,您已经请求的更改尚未生效的事实被暴露出来。framesomeOtherProperty会在上面的示例中返回它们的新值,这样您就不必关心更改是否立即生效,但根据您的观察performSelector:withObject:afterDelay:,您似乎偶然发现了更改不会假装的情况立即。

EAGLView很难诊断,因为它不是真正的 UIKit 功能。它所基于的CAEAGLLayer是,但EAGLView只是 Apple 为CAEAGLLayer在各种示例项目中构建的自定义 UIView 子类采用的名称。他们EAGLView在他们的示例中的接口或实现并不一致,但我猜测它可能正在创建 OpenGL 帧缓冲区对象(即 OpenGL 用来存储与像素相关的数字的东西,允许glReadPixels工作)仅在被要求布置时,并且在 UIKit 要求它这样做之前它不会布置自己。直到你退出运行循环。

可以通过检查EAGLView您拥有的代码来确认该诊断。如果由于或其他未由相关人员直接调用的方法而glGenFramebuffers触发了对此类事物的调用,layoutSubviews则可以证明这一点。drawRectinit

假设诊断是正确的,您可以适应EAGLView,但我认为最好的解决方案可能就是坚持performSelector:withObject:afterDelay:0. 这不是竞争条件,因此该解决方案一点也不可靠或不可靠,它只是一种稍微迂回的说法“让 UIKit 赶上所有这些指令,因为我知道这会让 EAGLView进入一个有意义的状态,然后继续我的东西”。

于 2011-08-14T02:00:50.283 回答