首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >EAGLView到UIImage计时问题

EAGLView到UIImage计时问题
EN

Stack Overflow用户
提问于 2011-08-13 08:18:33
回答 1查看 517关注 0票数 1

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

How to get UIImage from EAGLView?

但是,只有在创建EAGLView和创建UIImage之间经过了一小段时间后,我才能做到这一点。

这段代码先创建一个EAGLView,然后再创建一个UIImageView,这段代码不起作用:

代码语言:javascript
复制
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];

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

但是,上面代码的这个修改版本可以工作:

代码语言:javascript
复制
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更好的方法吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2011-08-14 10:00:50

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

代码语言:javascript
复制
view.frame = someNewFrame;
view.someOtherProperty = someOtherValue;

不要担心视图会在采用其他更改之前明显地采用新框架。通常,您希望对视图执行的操作看起来是原子的。

有时,您会遇到这样的情况,即您已经请求的更改尚未生效。在上面的示例中,framesomeOtherProperty将返回它们的新值,这样您就不必关心更改是否立即生效,但是根据您对performSelector:withObject:afterDelay:的观察,您很可能偶然发现了一种更改并不是立即生效的情况。

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

可以通过检查您拥有的EAGLView的代码来确认该诊断。如果有一堆像glGenFramebuffers这样的调用是由layoutSubviewsdrawRect或其他方法触发的,而这些方法并不是由相关的init直接调用的,那么这就证明了这一点。

假设诊断是正确的,您可以采用EAGLView,但我认为最好的解决方案可能就是坚持使用performSelector:withObject:afterDelay:0。这不是一个竞争条件,所以这个解决方案一点也不奇怪或不可靠,它只是一种稍微拐弯抹角的方式,意思是“让UIKit赶上所有这些指令,因为我知道这会让EAGLView进入一个有意义的状态,然后继续我的工作”。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/7047639

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档