扩展功能屏幕截图未捕获 iphone 和 ipad 中的相同区域
extension function screenshot not capturing the same area in iphone and ipad
我正在使用扩展功能截取 uiview 的屏幕截图。问题是结果看起来非常不同。我希望无论天气如何,照片看起来都一样 ipad 或 iphone。我手动输入约束,所以我希望图像是相同的。我想使用该函数转到 viewcontroller 的原点或中心,高度为 200,宽度为 200。因此无论设备如何,图像都应该相同,因为它从中心开始并且大小相同。
let vex = self.view.screenshot(for: CGRect(x: 0, y:UIScreen.main.bounds.size.height*0.65,, width: 100, height: 100), with: UIImage(named: "a.png"))
extension UIView {
/// Takes a screenshot of a UIView, with an option to clip to view bounds and place a waterwark image
/// - Parameter rect: offset and size of the screenshot to take
/// - Parameter clipToBounds: Bool to check where self.bounds and rect intersect and adjust size so there is no empty space
/// - Parameter watermark: UIImage of the watermark to place on top
func screenshot(for rect: CGRect, clipToBounds: Bool = true, with watermark: UIImage? = nil) -> UIImage {
var imageRect = rect
if clipToBounds {
imageRect = bounds.intersection(rect)
}
return UIGraphicsImageRenderer(bounds: imageRect).image { _ in
drawHierarchy(in: CGRect(origin: .zero, size: bounds.size), afterScreenUpdates: true)
watermark?.draw(in: CGRect(x: 0, y: 0, width: 32, height: 32))
}
}}
IPHONE
IPAD
//you used this
y:UIScreen.main.bounds.size.width*0.65,
//try this
y:UIScreen.main.bounds.size.height*0.65,
可能是你为 y 调用了 width 而不是 height :)
编辑:以上是一个错误,但没有解决问题。这是另一种可能的解决方案。
iphone 和 ipad 的屏幕尺寸不同。尝试将屏幕截图的大小扩大到 800x800,看看坐标是否因为您的屏幕尺寸而以某种方式偏离。似乎您的 200x200 没有延伸到导致不同结果的图形中。
看看下面的截图。
View hierarchy
-self.view
-blueView (subview of self.view)
-redView (subview of self.view)
请注意屏幕截图目标(基于 X = 0 和 Y = screen.y 乘数)如何因设备尺寸而异?使用提供的扩展,您可以根据视图层次结构以多种不同的方式解决上述问题。
如果您的层次结构仍然如上所列,您可以这样做:
选项 1
如果您想截取 blueView 内部的确切内容的屏幕截图,那么您可以这样做:(因为此 blueView 是 IBOutlet 或以编程方式设置的 属性)
let image = self.view.screenshot(for: blueView.frame, clipToBounds: true, with: UIImage(named: "star”))
上面为 self.view 的所有子视图在给定的矩形处截取了 self.view 的屏幕截图。 (下面的输出)
选项 2
如果您的视图层次结构更改为如下所示:
-self.view
- blueView(self.view 的子视图)
- redView(blueView 的子视图)
而你只想拍摄 blueView 和子视图的快照,那么你可以通过以下方式简化上面的操作:
let image = blueView.screenshot(for: blueView.bounds, with: UIImage(named: "star”))
这是可行的,因为 redView 是 blueView 的子视图(输出与上面的屏幕截图相同)
选项 3
现在假设你想在中心截取 self.view 的屏幕截图,屏幕截图大小为 300 那么你可以这样做
let size = CGSize(width: 300, height: 300) // notice this is bigger than blueView size
let rect = CGRect(origin: CGPoint(x: self.view.center.x - size.width / 2, y: self.view.center.y - size.height / 2), size: size)
let image = self.view.screenshot(for: rect, clipToBounds: false, with: UIImage(named: "star"))
这些都可以优化吗?是的,但我正在尝试逐步为您说明问题。 (下面是这个的输出)
对了,那些截图里的星星就是水印
对于那些想知道的人,OP 的扩展来自这个 并且从这个问题的时间开始它已经更新了一些。
我正在使用扩展功能截取 uiview 的屏幕截图。问题是结果看起来非常不同。我希望无论天气如何,照片看起来都一样 ipad 或 iphone。我手动输入约束,所以我希望图像是相同的。我想使用该函数转到 viewcontroller 的原点或中心,高度为 200,宽度为 200。因此无论设备如何,图像都应该相同,因为它从中心开始并且大小相同。
let vex = self.view.screenshot(for: CGRect(x: 0, y:UIScreen.main.bounds.size.height*0.65,, width: 100, height: 100), with: UIImage(named: "a.png"))
extension UIView {
/// Takes a screenshot of a UIView, with an option to clip to view bounds and place a waterwark image
/// - Parameter rect: offset and size of the screenshot to take
/// - Parameter clipToBounds: Bool to check where self.bounds and rect intersect and adjust size so there is no empty space
/// - Parameter watermark: UIImage of the watermark to place on top
func screenshot(for rect: CGRect, clipToBounds: Bool = true, with watermark: UIImage? = nil) -> UIImage {
var imageRect = rect
if clipToBounds {
imageRect = bounds.intersection(rect)
}
return UIGraphicsImageRenderer(bounds: imageRect).image { _ in
drawHierarchy(in: CGRect(origin: .zero, size: bounds.size), afterScreenUpdates: true)
watermark?.draw(in: CGRect(x: 0, y: 0, width: 32, height: 32))
}
}}
IPHONE
IPAD
//you used this
y:UIScreen.main.bounds.size.width*0.65,
//try this
y:UIScreen.main.bounds.size.height*0.65,
可能是你为 y 调用了 width 而不是 height :)
编辑:以上是一个错误,但没有解决问题。这是另一种可能的解决方案。
iphone 和 ipad 的屏幕尺寸不同。尝试将屏幕截图的大小扩大到 800x800,看看坐标是否因为您的屏幕尺寸而以某种方式偏离。似乎您的 200x200 没有延伸到导致不同结果的图形中。
看看下面的截图。
View hierarchy
-self.view
-blueView (subview of self.view)
-redView (subview of self.view)
请注意屏幕截图目标(基于 X = 0 和 Y = screen.y 乘数)如何因设备尺寸而异?使用提供的扩展,您可以根据视图层次结构以多种不同的方式解决上述问题。 如果您的层次结构仍然如上所列,您可以这样做:
选项 1 如果您想截取 blueView 内部的确切内容的屏幕截图,那么您可以这样做:(因为此 blueView 是 IBOutlet 或以编程方式设置的 属性)
let image = self.view.screenshot(for: blueView.frame, clipToBounds: true, with: UIImage(named: "star”))
上面为 self.view 的所有子视图在给定的矩形处截取了 self.view 的屏幕截图。 (下面的输出)
选项 2 如果您的视图层次结构更改为如下所示: -self.view - blueView(self.view 的子视图) - redView(blueView 的子视图)
而你只想拍摄 blueView 和子视图的快照,那么你可以通过以下方式简化上面的操作:
let image = blueView.screenshot(for: blueView.bounds, with: UIImage(named: "star”))
这是可行的,因为 redView 是 blueView 的子视图(输出与上面的屏幕截图相同)
选项 3 现在假设你想在中心截取 self.view 的屏幕截图,屏幕截图大小为 300 那么你可以这样做
let size = CGSize(width: 300, height: 300) // notice this is bigger than blueView size
let rect = CGRect(origin: CGPoint(x: self.view.center.x - size.width / 2, y: self.view.center.y - size.height / 2), size: size)
let image = self.view.screenshot(for: rect, clipToBounds: false, with: UIImage(named: "star"))
这些都可以优化吗?是的,但我正在尝试逐步为您说明问题。 (下面是这个的输出)
对了,那些截图里的星星就是水印
对于那些想知道的人,OP 的扩展来自这个