【问题标题】:iPhone demo help: anyone know of a faster screen capture alternative to UIGetScreenImage()?iPhone 演示帮助:有人知道 UIGetScreenImage() 的更快屏幕捕获替代方案吗?
【发布时间】:2011-06-12 04:46:08
【问题描述】:

我正在开发一个 iPhone 应用程序,我将很快向现场观众演示。

我真的很想在投影仪上通过 VGA 现场演示应用程序,而不是显示屏幕截图。

我为 iPhone 购买了一个 VGA 适配器,并调整了 Rob Terrell's TVOutManager 以满足我的需要。不幸的是,在我家的电视上测试后的帧速率并不是那么好——即使在 iPhone 4 上也是如此(可能每秒 4-5 帧,它会有所不同)。

我认为这种缓慢的原因是我用来捕获设备屏幕(然后显示在外部显示器上)的主要例程是UIGetScreenImage()。这个不再被允许成为应用程序的一部分的例程实际上非常慢。这是我用来捕获屏幕的代码(仅供参考mirrorViewUIImageView):

CGImageRef cgScreen = UIGetScreenImage();
self.mirrorView.image = [UIImage imageWithCGImage:cgScreen];
CGImageRelease(cgScreen);

我可以使用更快的方法来捕捉 iPhone 的屏幕并获得更好的帧速率(拍摄 20+ fps)吗?它不需要通过 Apple 的应用程序审查 - 此演示代码不会在发货应用程序中。如果有人知道任何更快的私有 API,我将非常感谢您的帮助!

此外,上面的代码正在使用重复的NSTimer 执行,它每1.0/desiredFrameRate 秒(当前每0.1 秒)触发一次。我想知道是否将这些调用包装在一个块中并使用 GCD 或NSOperationQueue 可能比让NSTimer 调用我当前包含这些调用的updateTVOut obj-c 方法更有效。对此也很感激 - 一些搜索似乎表明 obj-c 消息发送与其他操作相比有些慢。

最后,正如您在上面看到的,UIGetScreenImage() 返回的CGImageRef 被转换为UIImage,然后UIImage 被传递给UIImageView,这可能正在调整图像大小苍蝇。我想知道调整大小是否会进一步减慢速度。关于如何更快地做到这一点的想法?

【问题讨论】:

    标签: iphone ios screen-capture iphone-privateapi


    【解决方案1】:

    新解决方案:获取 iPad 2 并镜像输出! :)

    【讨论】:

      【解决方案2】:

      我不知道这有多快,但值得一试;)

      CGImageRef screenshot = [[UIApplication sharedApplication] _createDefaultImageSnapshot];
      [myVGAView.layer setContents:(id)screenshot];
      

      _createDefaultImageSnapshot 是私有 API。 (因为是演示......我想没关系) 而myVGAView 是一个普通的 UIView。 如果你得到 CGImageRefs 则只需将它们传递给层的内容,它更轻并且应该更快一点(但只是一点点;))

      【讨论】:

        【解决方案3】:

        我没有您想要的解决方案(模拟视频镜像),但您可以将视图移至外部显示器。这就是我所做的,对帧速率没有明显影响。然而,显然由于视图不再在设备的屏幕上,您不能再直接与其交互或查看它。如果您有类似由加速度计控制的游戏,这应该不是问题,但是基于触摸的东西需要一些工作。当主要视图是外部视图时,我所做的是在设备上有一个替代视图。对我来说,这是一个“命令”正常 3D 视图的 2D 控制视图。如果你有一个游戏,你也许可以创建一个替代输入视图来控制游戏(虚拟按钮/操纵杆等),这取决于你有什么来最好地解决它。

        我自己没有越狱我不能肯定地说,但我的印象是越狱设备基本上可以启用视频镜像(就像他们在苹果演示中使用的那样......)。如果属实,如果您想要的只是演示,这可能是您最简单的方法。

        【讨论】:

          【解决方案4】:

          您是否查看过 Apple 推荐的 UIGetScreenImage 替代方案?来自“Notice regarding UIGetScreenImage()”线程:

          使用 UIGetScreenImage() 从相机捕获图像的应用程序应该使用 AVCaptureSession 和 AV Foundation 框架中的相关类。例如,请参阅Technical Q&A QA1702,“如何使用 AV Foundation 将摄像机中的视频帧捕获为图像”。请注意,仅 iOS4 及更高版本支持使用 AVCaptureSession。

          使用 UIGetScreenImage() 来捕获界面视图和层的内容的应用程序应该使用 QuartzCore 框架中 CALayer 的 -renderInContext: 方法。有关示例,请参阅Technical Q&A QA1703,“UIKit 应用程序中的屏幕截图”。

          使用 UIGetScreenImage() 来捕获基于 OpenGL ES 的视图和层的内容的应用程序应该使用 glReadPixels() 函数来获取像素数据。有关示例,请参阅Technical Q&A QA1704,“OpenGL ES 视图快照”。

          【讨论】:

          • 您好乔纳,感谢您的建议。事实证明,我确实尝试过使用 CALayer 的 renderInContext: 方法。它甚至更慢。在这种情况下,AVFoundation 也不会真正帮助我,因为我不是从相机或其他 AV 源捕获 - 我正在尝试捕获屏幕本身。 Apple 推荐 UIGetScreenImage 的替代品,因为它们不再允许使用它,但此代码不是用于 App Store 提交,它只是用于演示。
          猜你喜欢
          • 2011-05-13
          • 1970-01-01
          • 2021-10-17
          • 1970-01-01
          • 1970-01-01
          • 2013-03-21
          • 1970-01-01
          • 1970-01-01
          • 2018-12-11
          相关资源
          最近更新 更多