我有一个EAGLView,希望将其转换为UIImage。我可以使用此处发布的解决方案来做到这一点:
How to get UIImage from EAGLView?
但是,只有在创建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];
我假设在创建EAGLView之前尝试创建UIImageView。我试图在两者之间放一个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()错误吗?有没有比我的黑客更好的方法?
最佳答案
通常,当您对UIKit对象进行可见更改而不是立即更新时,它们只是标记自己以在将来进行更改,然后在下次您放弃主线程时(通过返回运行循环)批量处理整个更改。这不是功能失常或实现失败,实际上通常是您隐含的期望,这是您可以编写如下代码的原因:
view.frame = someNewFrame;
view.someOtherProperty = someOtherValue;
不必担心视图经常会在采用其他更改之前明显采用新框架。通常,您希望对视图执行的操作看起来是原子的。
有时您会遇到一种情况,就像您在这里遇到的那样,这种情况已经暴露出您已经请求的更改尚未生效的事实。在上面的示例中,
frame
和someOtherProperty
将返回它们的新值,因此您不必担心更改是否立即生效,但是基于对performSelector:withObject:afterDelay:
的观察,您似乎偶然发现了这种情况并不意味着立即发生变化。EAGLView
很难诊断,因为它实际上不是UIKit功能。它是基于CAEAGLLayer
构建的,但EAGLView
只是Apple在各种示例项目中为基于CAEAGLLayer
构建的自定义UIView子类采用的名称。他们在示例中关于EAGLView
的接口或实现并不一致,但是我猜想这可能是在创建OpenGL帧缓冲区对象(即OpenGL用于存储与像素,允许glReadPixels
起作用)仅在被要求进行布局时才会出现,并且直到UIKit要求进行布局时才进行布局。直到您退出运行循环,才可以这样做。可以通过检查您拥有的
EAGLView
的代码来确认该诊断。如果由于glGenFramebuffers
,layoutSubviews
或相关drawRect
未直接调用的其他方法而触发了对init
之类的大量调用,则证明了这一点。假设诊断正确,您可以改写
EAGLView
,但是我认为最好的解决方案就是坚持使用performSelector:withObject:afterDelay:0
。这不是争用条件,因此解决方案并非一帆风顺或不可靠,它只是说“让UIKit赶上所有这些指令,因为我知道这会让EAGLView成为现实”进入有意义的状态,然后继续我的东西”。关于iphone - EAGLView到UIImage的计时问题,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/7047639/