使用 renderInContext 将视图层保存到图像

Posted

技术标签:

【中文标题】使用 renderInContext 将视图层保存到图像【英文标题】:Save view layer to image with renderInContext 【发布时间】:2015-02-26 22:26:17 【问题描述】:

我正在尝试将我的 tableView 图层保存为图像,并且一切都按预期工作。

但是,它只会保存 tableView 中在视图上实际可见的部分;如果 tableView 比显示长(并且您必须向下滚动才能看到它),则该部分不会保存在创建的图像中

我确定我在这里忽略了一些东西,它不允许它保存当前视图之外的任何部分。我很感激有人指出我正确的方向。谢谢!

UIGraphicsBeginImageContextWithOptions(self.view.bounds.size, self.view.opaque, 0.0);

[self.tableView.layer renderInContext:UIGraphicsGetCurrentContext()];

UIImage *imageView = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

UIImageWriteToSavedPhotosAlbum(imageView, self, @selector(image:finishedSavingWithError:contextInfo:),nil);

【问题讨论】:

【参考方案1】:

你有两种方法可以解决这个问题,有些方法比其他方法好,各有利弊。

如果您的表格视图没有增长到很大的大小,您可以将其调整为内容大小,渲染然后将其恢复为原始大小。这很容易,但是随着越来越多的单元格添加到表格视图中,内存压力和 CPU 使用率也会随着您调整表格视图的大小而增加,因为所有单元格都需要加载并准备好显示。

另一种选择是将内容分成几个图块,并在最后连接图块,但将表格视图的内容偏移设置为第一页、第二页等。这样可以节省内存,但不会节省 CPU,因为您仍然需要配置单元格。此外,考虑到内容偏移,将各个部分拼接在一起的任务更加艰巨。

【讨论】:

【参考方案2】:

我建议将所有必要的内容自定义绘制到您的上下文中,而不是制作屏幕截图。这可能很复杂,但至少你不依赖 UI hack。此外,通过这种方法,您可以在不同的线程上执行绘图 - 因此您的应用不会冻结一段时间 - 当表格视图很大时,这可能会非常明显。

无论如何,我不建议您修改当前的表格视图参数来制作屏幕截图 - 最好为此创建额外的表格视图。

【讨论】:

【参考方案3】:
UIGraphicsBeginImageContextWithOptions(self.view.bounds.size, self.view.opaque, 0.0);

此方法返回一个带有您传递的选项的位图

第一个参数是 size 并且,pixel 中的最终位图大小是 size 值,乘以 scale em> 因素(在您的情况下为 0.0f,这意味着在您的情况下为 1.0f)。 因此,使用此位图大小准备上下文,您将永远无法获得 整个 tableView 位图。

尝试修改 size 参数传递它self.tableView.bounds.size

Apple Doc

要获得以像素为单位的位图大小,必须将宽度和高度值乘以缩放参数中的值。

【讨论】:

以上是关于使用 renderInContext 将视图层保存到图像的主要内容,如果未能解决你的问题,请参考以下文章

iOS:renderInContext 和横向方向问题

layer.renderInContext 不考虑 layer.mask?

带有阴影的 UIView - 应用 renderInContext 时速度很慢

renderInContext在背景线程上创建黑色背景

带有 renderInContext 的 iPad 3 设备崩溃

在相机视图中保存带有叠加层的图像