【问题标题】:Why does my programmatically created screenshot look so bad on iOS 7?为什么我以编程方式创建的屏幕截图在 iOS 7 上看起来如此糟糕?
【发布时间】:2013-09-28 04:38:44
【问题描述】:

我正在尝试实现与 facebook 的共享应用程序。 我使用此代码截取屏幕截图:

CGSize imageSize = CGSizeMake(self.view.bounds.size.width, self.view.bounds.size.height);
UIGraphicsBeginImageContext(imageSize);
[self.view.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *viewImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

它在 iOS 6 上运行良好,但在 iOS 7 中图像看起来很糟糕。 我用了这个答案:iOS: what's the fastest, most performant way to make a screenshot programmatically? 试图修复它,它有帮助,但屏幕截图看起来仍然很糟糕。 屏幕得到另一种颜色,并且某些对象(如标签)未显示在拍摄的图像上。 有什么帮助吗?

----更新----

我设法解决了大多数对象,将它们更改为保留而不是弱。我的主要问题仍然是我的表格视图,它显示为一个大的白色块(它应该是透明的,带有白色文本的标签,所以我们看到的只是白色单元格)。我确实尝试将表格背景定义为 clearcolor,没有帮助..

----上次更新---

这里有一些很棒的答案,与我的问题无关。我想让它在运行 iOS7 但不使用 iOS7 SDK 的设备上运行,因为此时切换项目 SDK 需要付出很多努力,当项目快完成时。

无论如何,我添加的代码最终解决了我的问题:

这个改动简单解决了问题:

UIGraphicsBeginImageContextWithOptions(imageSize, NO , 0.0f);

代替:

UIGraphicsBeginImageContext(imageSize);

【问题讨论】:

    标签: ios objective-c iphone xcode screenshot


    【解决方案1】:

    在 iOS 8 中:这就是我获取 ScreenShot 的方式

    1. 刚刚在.h文件中添加了一个UIImageView和截屏方法

    @property (weak, nonatomic) IBOutlet UIImageView *imageView;

     -(IBAction)takeSnapShot:(id)sender;
    

    2 添加了用于截屏并在 UIImageView 上设置的代码片段在 .m 文件中

    - (IBAction)takeSnapShot:(id)sender
    {
        UIGraphicsBeginImageContext(self.view.bounds.size);
        [self.view.layer renderInContext:UIGraphicsGetCurrentContext()];
        UIImage *snapShotImage = UIGraphicsGetImageFromCurrentImageContext();
        UIGraphicsEndImageContext();
    
        imageView.image = snapShotImage;
    }
    
    1. 下面是我得到的输出。

    【讨论】:

      【解决方案2】:

      在 iOS7 上,如果您使用,可能会出现故障

      [view drawViewHierarchyInRect:view.bounds afterScreenUpdates:YES]
      

      在正在进行的动画中。设置afterScreenUpdates = NO 以消除故障。

      【讨论】:

      • 谢谢!在过去的 3 个小时里,每当我捕捉到屏幕时,我都会因为奇怪的故障而发疯。我的代码在 applicationDidEnterBackground: 中被调用,它导致任何动画在返回应用程序时冻结。
      【解决方案3】:

      确保opaque 设置为NO

      【讨论】:

      • renderInContext 是纯 CPU 合成和渲染,它处理不透明度标志的方式与基于常规 OpenGL 的合成引擎不同
      【解决方案4】:

      你可以试试这个

      - (UIImage *) screenshot {
          UIGraphicsBeginImageContextWithOptions(self.view.bounds.size, NO, [UIScreen mainScreen].scale);
      
          [self.view drawViewHierarchyInRect:self.view.bounds afterScreenUpdates:YES];
      
          UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
          UIGraphicsEndImageContext();
          return image;
      }
      

      【讨论】:

      • 和这里的第一个答案一样,这是新的 iOS 7 API。我的应用程序远未得到 iOS 7 SDK 的支持。将来会,但我现在需要一个解决方案:)
      • 如何在 iOS 的任何视图中截屏,而不仅仅是在我的应用内?
      • [self.view drawViewHierarchyInRect:self.view.bounds afterScreenUpdates:YES];在我的 iPhone 6 上会使整个屏幕闪烁。我必须使用“[self.view drawViewHierarchyInRect:self.view.bounds afterScreenUpdates:NO];”反而。为什么会这样?
      • 规模对于最佳质量很重要
      【解决方案5】:

      自 iOS 7 以来添加了新的API,它应该提供获取快照的有效方式

      • snapshotViewAfterScreenUpdates: 将视图呈现为 UIView,其中 content 不可修改

      • resizableSnapshotViewFromRect:afterScreenUpdates:withCapInsets :同样的东西,但具有可调整大小的插图

      • drawViewHierarchyInRect:afterScreenUpdates: :如果您还需要绘制所有子视图(如标签、按钮...),则同样的事情

      您可以将返回的UIView 用于任何 UI 效果,或者在需要导出时像您所做的那样渲染成图像。

      我不知道这种新方法与您提供的方法相比有多好(尽管我记得 Apple 工程师说这种新 API 更有效)

      【讨论】:

      • 感谢您的回答。我的应用程序现在不兼容 iOS 7 SDK。我没有时间进行所有必要的更改并替换所有已弃用的类。我正在使用 iOS 6 SDK 在 iOS7 上运行我的应用程序。我在所有应用程序中遇到的唯一问题是这个屏幕截图。你知道我该怎么做吗?
      • 我认为,您当前代码的 1 个问题可能是没有考虑比例(设备是 Retina 吗?)。你可以使用UIGraphicsBeginImageContextWithOptions(imageSize, NO, 0.0)(最后一个参数是图像的比例,设置0.0确保函数选择设备主屏幕的比例)
      • 您的评论与我最终使用的解决方案最接近 :)
      • @Vinzzz,谢谢你的回答,我认为你的方法可以用来在我的应用程序中截取屏幕截图,但是如果我想截取整个屏幕的截图,无论哪个应用程序处于活动状态,包括主屏幕,我能做什么。事实上,我的应用程序是在 SpringBoard 中运行的越狱调整应用程序,我想为任何活动的应用程序捕获屏幕截图。
      • @Suge :在这种情况下,这取决于您使用的越狱提供的内容。 Apple 没有提供任何 API(据我所知)来访问其他应用程序 UI。
      猜你喜欢
      • 1970-01-01
      • 2023-03-19
      • 2011-01-13
      • 2015-09-25
      • 1970-01-01
      • 2013-08-25
      • 1970-01-01
      • 1970-01-01
      • 2016-03-18
      相关资源
      最近更新 更多