- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我知道这个问题得到了很多回答,但我的情况似乎有所不同。我正在尝试编写一个顶层函数,我可以随时截取我的应用程序的屏幕截图,无论是 openGLES 还是 UIKit,我都无法访问底层类来进行任何更改。
我一直在尝试的代码适用于 UIKit,但返回 OpenGLES 部分的黑屏
CGSize imageSize = [[UIScreen mainScreen] bounds].size;
if (NULL != UIGraphicsBeginImageContextWithOptions)
UIGraphicsBeginImageContextWithOptions(imageSize, NO, 0);
else
UIGraphicsBeginImageContext(imageSize);
CGContextRef context = UIGraphicsGetCurrentContext();
// Iterate over every window from back to front
for (UIWindow *window in [[UIApplication sharedApplication] windows])
{
if (![window respondsToSelector:@selector(screen)] || [window screen] == [UIScreen mainScreen])
{
// -renderInContext: renders in the coordinate space of the layer,
// so we must first apply the layer's geometry to the graphics context
CGContextSaveGState(context);
// Center the context around the window's anchor point
CGContextTranslateCTM(context, [window center].x, [window center].y);
// Apply the window's transform about the anchor point
CGContextConcatCTM(context, [window transform]);
// Offset by the portion of the bounds left of and above the anchor point
CGContextTranslateCTM(context,
-[window bounds].size.width * [[window layer] anchorPoint].x,
-[window bounds].size.height * [[window layer] anchorPoint].y);
for (UIView *subview in window.subviews)
{
CAEAGLLayer *eaglLayer = (CAEAGLLayer *) subview.layer;
if([eaglLayer respondsToSelector:@selector(drawableProperties)]) {
NSLog(@"reponds");
/*eaglLayer.drawableProperties = @{
kEAGLDrawablePropertyRetainedBacking: [NSNumber numberWithBool:YES],
kEAGLDrawablePropertyColorFormat: kEAGLColorFormatRGBA8
};*/
UIImageView *glImageView = [[UIImageView alloc] initWithImage:[self snapshotx:subview]];
glImageView.transform = CGAffineTransformMakeScale(1, -1);
[glImageView.layer renderInContext:context];
//CGImageRef iref = [self snapshot:subview withContext:context];
//CGContextDrawImage(context, CGRectMake(0.0, 0.0, 640, 960), iref);
}
[[window layer] renderInContext:context];
// Restore the context
CGContextRestoreGState(context);
}
}
}
// Retrieve the screenshot image
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return image;
和
- (UIImage*)snapshotx:(UIView*)eaglview
{
GLint backingWidth, backingHeight;
//glBindRenderbufferOES(GL_RENDERBUFFER_OES, _colorRenderbuffer);
//don't know how to access the renderbuffer if i can't directly access the below code
// Get the size of the backing CAEAGLLayer
glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_WIDTH_OES, &backingWidth);
glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_HEIGHT_OES, &backingHeight);
NSInteger x = 0, y = 0, width = backingWidth, height = backingHeight;
NSInteger dataLength = width * height * 4;
GLubyte *data = (GLubyte*)malloc(dataLength * sizeof(GLubyte));
// Read pixel data from the framebuffer
glPixelStorei(GL_PACK_ALIGNMENT, 4);
glReadPixels(x, y, width, height, GL_RGBA, GL_UNSIGNED_BYTE, data);
// Create a CGImage with the pixel data
// If your OpenGL ES content is opaque, use kCGImageAlphaNoneSkipLast to ignore the alpha channel
// otherwise, use kCGImageAlphaPremultipliedLast
CGDataProviderRef ref = CGDataProviderCreateWithData(NULL, data, dataLength, NULL);
CGColorSpaceRef colorspace = CGColorSpaceCreateDeviceRGB();
CGImageRef iref = CGImageCreate (
width,
height,
8,
32,
width * 4,
colorspace,
// Fix from Apple implementation
// (was: kCGBitmapByteOrder32Big | kCGImageAlphaPremultipliedLast).
kCGBitmapByteOrderDefault,
ref,
NULL,
true,
kCGRenderingIntentDefault
);
// OpenGL ES measures data in PIXELS
// Create a graphics context with the target size measured in POINTS
NSInteger widthInPoints, heightInPoints;
if (NULL != UIGraphicsBeginImageContextWithOptions)
{
// On iOS 4 and later, use UIGraphicsBeginImageContextWithOptions to take the scale into consideration
// Set the scale parameter to your OpenGL ES view's contentScaleFactor
// so that you get a high-resolution snapshot when its value is greater than 1.0
CGFloat scale = eaglview.contentScaleFactor;
widthInPoints = width / scale;
heightInPoints = height / scale;
UIGraphicsBeginImageContextWithOptions(CGSizeMake(widthInPoints, heightInPoints), NO, scale);
}
else {
// On iOS prior to 4, fall back to use UIGraphicsBeginImageContext
widthInPoints = width;
heightInPoints = height;
UIGraphicsBeginImageContext(CGSizeMake(widthInPoints, heightInPoints));
}
CGContextRef cgcontext = UIGraphicsGetCurrentContext();
// UIKit coordinate system is upside down to GL/Quartz coordinate system
// Flip the CGImage by rendering it to the flipped bitmap context
// The size of the destination area is measured in POINTS
CGContextSetBlendMode(cgcontext, kCGBlendModeCopy);
CGContextDrawImage(cgcontext, CGRectMake(0.0, 0.0, widthInPoints, heightInPoints), iref);
// Retrieve the UIImage from the current context
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
// Clean up
free(data);
CFRelease(ref);
CFRelease(colorspace);
CGImageRelease(iref);
return image;
}
关于如何在无法修改应用程序其余部分中的类的情况下混合两者的任何建议?
谢谢!
最佳答案
我看到你在那里尝试做什么,这并不是一个坏主意。不过似乎确实存在一个大问题:您不能随时调用 glReadPixels
。首先,您应该确保缓冲区充满了您真正需要的数据(像素),其次,它应该在其 GL 部分正在处理的同一线程上调用...
如果 GL View 不是您的,您可能会在调用该屏幕截图方法时遇到一些大麻烦,您需要调用一些方法来触发绑定(bind)其内部上下文,如果它是动画的,您将必须知道循环何时完成确保您收到的像素与 View 中显示的像素相同。
无论如何,如果你通过了所有这些,你可能仍然需要“跳转”不同的线程或者需要等待一个循环完成。在这种情况下,我建议您使用返回屏幕截图图像的 block ,该图像应作为方法参数传递,以便您可以在返回时捕获它。也就是说,如果您可以重写 GL View 上的一些方法以便能够通过回调 block 向您返回屏幕截图图像并编写一些递归系统,那将是最好的。
总而言之,您需要预见到多线程、设置上下文、绑定(bind)正确的帧缓冲区,等待所有内容被渲染。这一切都可能导致无法创建一个可以在不重载某些内部方法的情况下简单地适用于任何应用程序、 View 、系统的屏幕截图方法。
请注意,您根本不允许在您的应用程序中制作整个屏幕截图(例如同时按下主页和锁定按钮的屏幕截图)。至于 UIView 部分很容易从中创建图像是因为 UIView 被重新绘制到独立于屏幕的图形上下文中;就好像您可以采用一些 GL 管道并将其绑定(bind)到您自己的缓冲区和上下文并绘制它,这将导致能够独立获取其屏幕截图并可以在任何线程上执行。
关于ios - 从父类中混合 OpenGLES 和 UIKIT 获取 iOS 屏幕截图,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17013970/
我知道您不应该将打印与 printf,cout 和 wprintf,wcout 混合使用,但是很难找到一个好的答案,为什么以及是否可以绕过它。问题是我使用了一个用 printf 打印的外部库,而我自己
我有以下问题: class A: animal = 'gerbil' def __init__(self): self.result = self.calculate_
我在屏幕上渲染了一堆形状(多边形),我没有使用深度测试。 我只是希望这些形状在绘制在空白区域时使用自己的颜色,并且在绘制到任何非空区域时使用红色像素,即在我的情况下绘制在另一个多边形上。 这里的问题实
我正在尝试在我的 Groovy/Grails 应用程序中混入一个类,我正在使用 the syntax defined in the docs ,但我不断收到错误消息。 我有一个如下所示的域类: cla
我已经找到了 5349574673 个关于 Alpha 混合的页面,但我仍然无法获得想要的结果。我正在尝试使用 opengl 使 gif/png 文件正确显示(具有透明度/半透明度)。 这是我的初始化
我正在尝试记录以下代码,但我似乎无法让 JSDoc 记录该类,甚至无法引用它的存在。 // SomeMixin.js export default superclass => class SomeMi
我有一个类型家族,我想使用 mixin 以模块化方式“丰富”它们。例如: trait Family { self => trait Dog { def dogname:String
我在 Storyboard中有 Collection View 。我在 Storyboard中有一部分单元格,还有我以编程方式创建的部分单元格。我应该在 sizeForItemAtIndexPath
我有一个字节数组,我想更改它的访问方式。这是数组: char bytes[100]; 我想要另一个数组来改变原始数组的访问方式。如果我们可以将引用放在数组中,它看起来像这样: char& bytes_
我需要从 c 文件调用 cpp 方法。我为此编写了这个界面.. cpp文件 extern "C" void C_Test(int p){ Class::CPP_Test(p); } c文件
我的网站有两份 CSS 表,一份是主 CSS,一份是移动 CSS。问题是在移动设备(iPhone、Android)上查看时,两个样式表会混淆。例如,在 iPhone 上查看网站时,会应用主样式表中的某
维护人员的说明:此问题涉及已过时的 bokeh.charts API,该 API 已于多年前删除。有关使用现代 Bokeh 创建各种条形图的信息,请参阅: https://docs.bokeh.org
在下图中,蓝色圆圈仅用于调试目的。我的目标是蓝色圆圈后面的每一层都应该是透明的。我只想保持蓝色圆圈外面的可见。 这是用 swift 编写的代码: let croissantView = UIV
我不是 SQL 专家。我正在使用 SQL Server 2005,我正在尝试弄清楚如何构造一个查询,以便它可以满足多种要求。我有两个表定义如下: Classroom - ID - Departme
原创: 我之前问过这个问题,但我最初的例子有点不完整,我想我现在可以更具体地说明我的问题。 对于上下文,我在旧的 Apple mac 计算机上使用 openGL 3.3 并尝试渲染四边形的重叠层。每个
是否可以将内联(类似 json)映射与同一对象的常规映射定义混合使用? 考虑以下示例: person: {age: 32, weight: 82} name: foo 生成的人应具有给定的年龄、体
假设我有一个 Parent 类,它有四个字段 A、B、C 和 D,这样 C 和 D 可以选择传递或使用默认实现进行初始化: open class Parent(val a: A, val b: B,
我正在使用 symphony (1.4) 框架在 PHP 中开发一个 Web 应用程序。该代码使用 SVN 进行版本控制。在此网络应用程序中,我们所有客户共享一个共同的基础,以及一些专门为每个客户创建
我想使用两个小部件(一次一个)作为我的应用程序的基础/背景,上面有一个 QML UI 和一个无边框窗口。它应该看起来像这样: 基于 OpenGL 的扫描组件 通过窗口句柄操作的 3D 可视化组件 多个
我们有一个混合的 AngularJS/Angular 8 应用程序,并且我们不断遇到来自不同版本框架的组件之间的变化检测非常慢的问题。到目前为止,我们只在 Angular 组件中使用 AngularJ
我是一名优秀的程序员,十分优秀!