[英]iOS Take Screenshot on Curent Device Display not App Screen
我有这些代码(用 C# 编写)来截取屏幕截图,但它只截取 App Screen,即使我最小化我的应用程序,它仍然会捕获我的 App 屏幕。 我想占据整个设备屏幕,即使我打开另一个应用程序,它也会显示其他应用程序、桌面等的屏幕截图......
在 C# Xamarin
var view = UIApplication.SharedApplication.KeyWindow.RootViewController.View;
UIGraphics.BeginImageContext(view.Frame.Size);
view.DrawViewHierarchy(view.Frame, true);
var image = UIGraphics.GetImageFromCurrentImageContext();
UIGraphics.EndImageContext();
using (var imageData = image.AsPNG())
{
var bytes = new byte[imageData.Length];
System.Runtime.InteropServices.Marshal.Copy(imageData.Bytes, bytes, 0, Convert.ToInt32(imageData.Length));
return bytes;
}
你也可以在 Swift/Objective-C 中发布建议。
不幸的是,这是不可能的。 出于安全原因,iOS 不允许应用程序截取除它们自己的视图层次结构之外的任何内容。
更新:澄清一下,在您的应用程序中获取其他应用程序屏幕截图的唯一方法是让用户手动截取屏幕截图(使用主页 + 电源按钮),然后让用户将其发送/共享到您的应用程序(通过支持和处理图像文件类型),或者让用户从他们的照片库中选择它(使用UIImagePickerController )。
目前没有选项可以完全自动化此过程。
在您的情况下,您应该使用UIScreen的View
而不是当前的ViewController 。
CGSize size = UIScreen.MainScreen.Bounds.Size;
nfloat scale = UIScreen.MainScreen.Scale;
UIGraphics.BeginImageContextWithOptions(size,true,scale);
UIApplication.SharedApplication.KeyWindow.Layer.RenderInContext(UIGraphics.GetCurrentContext());
UIImage image = UIGraphics.GetImageFromCurrentImageContext();
UIGraphics.EndImageContext();
如果你想让屏幕截图包含状态栏,你可以参考下面的 OC 代码
+ (UIImage *)screenshotWithStatusBar:(BOOL)withStatusBar rect:(CGRect)rect
{
UIInterfaceOrientation o = [[UIApplication sharedApplication] statusBarOrientation];
return [self screenshotWithStatusBar:withStatusBar rect:rect orientation:o];
}
+ (UIImage *)screenshotWithStatusBar:(BOOL)withStatusBar rect:(CGRect)rect orientation:(UIInterfaceOrientation)o
{
CGRect screenRect = [[UIScreen mainScreen] bounds];
CGFloat screenWidth = CGRectGetWidth(screenRect);
CGFloat screenHeight = CGRectGetHeight(screenRect);
CGAffineTransform preTransform = CGAffineTransformIdentity;
switch (o)
{
case UIInterfaceOrientationPortrait:
//move screenshot rect origin to down left
//rotate screenshot rect to meet portrait
//move screenshot rect origin to up left
//....yes, with a single line..
preTransform = CGAffineTransformTranslate(preTransform, -rect.origin.x, -rect.origin.y);
break;
case UIInterfaceOrientationPortraitUpsideDown:
//move screenshot rect origin to down left
preTransform = CGAffineTransformTranslate(preTransform, screenWidth - rect.origin.x, -rect.origin.y);
//rotate screenshot rect to meet portrait
preTransform = CGAffineTransformRotate(preTransform, M_PI);
//move screenshot rect origin to up left
preTransform = CGAffineTransformTranslate(preTransform, 0, -screenHeight);
break;
case UIInterfaceOrientationLandscapeLeft:
//move screenshot rect origin to down left
preTransform = CGAffineTransformTranslate(preTransform, -rect.origin.x, -rect.origin.y);
//rotate screenshot rect to meet portrait
preTransform = CGAffineTransformRotate(preTransform, M_PI_2);
//move screenshot rect origin to up left
preTransform = CGAffineTransformTranslate(preTransform, 0, -screenHeight);
break;
case UIInterfaceOrientationLandscapeRight:
//move screenshot rect origin to down left
preTransform = CGAffineTransformTranslate(preTransform, screenHeight - rect.origin.x, screenWidth - rect.origin.y);
//rotate screenshot rect to meet portrait
preTransform = CGAffineTransformRotate(preTransform, - M_PI_2);
//move screenshot rect origin to up left
preTransform = CGAffineTransformTranslate(preTransform, 0, -screenHeight);
break;
default:
break;
}
// Create a graphics context with the target size
UIGraphicsBeginImageContextWithOptions(rect.size, NO, 0);
CGContextRef context = UIGraphicsGetCurrentContext();
BOOL hasTakenStatusBarScreenshot = NO;
// 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);
// Apply pre tranform to context.
// to convert all interface orientation situation to portrait situation.
CGContextConcatCTM(context, preTransform);
// 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);
// Render the layer hierarchy to the current context
if ([window respondsToSelector:@selector(drawViewHierarchyInRect:afterScreenUpdates:)]) {
[window drawViewHierarchyInRect:window.bounds afterScreenUpdates:YES];
} else {
[window.layer renderInContext:context];
}
// Restore the context
CGContextRestoreGState(context);
}
// Screenshot status bar if next window's window level > status bar window level
NSArray *windows = [[UIApplication sharedApplication] windows];
NSUInteger currentWindowIndex = [windows indexOfObject:window];
if (windows.count > currentWindowIndex + 1)
{
UIWindow *nextWindow = [windows objectAtIndex:currentWindowIndex + 1];
if (withStatusBar && nextWindow.windowLevel > UIWindowLevelStatusBar && !hasTakenStatusBarScreenshot)
{
[self mergeStatusBarToContext:context rect:rect screenshotOrientation:o];
hasTakenStatusBarScreenshot = YES;
}
}
else
{
if (withStatusBar && !hasTakenStatusBarScreenshot)
{
[self mergeStatusBarToContext:context rect:rect screenshotOrientation:o];
hasTakenStatusBarScreenshot = YES;
}
}
}
// Retrieve the screenshot image
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return image;
}
+ (void)mergeStatusBarToContext:(CGContextRef)context
rect:(CGRect)rect
screenshotOrientation:(UIInterfaceOrientation)o
{
UIView *statusBarView = [UIView statusBarInstance_ComOpenThreadOTScreenshotHelper];
UIInterfaceOrientation statusBarOrientation = [[UIApplication sharedApplication] statusBarOrientation];
CGFloat screenWidth = [[UIScreen mainScreen] bounds].size.width;
CGFloat screenHeight = [[UIScreen mainScreen] bounds].size.height;
CGAffineTransform preTransform = CGAffineTransformIdentity;
if (o == statusBarOrientation)
{
preTransform = CGAffineTransformTranslate(preTransform, -rect.origin.x, -rect.origin.y);
}
//Handle status bar orientation in portrait and portrait upside down screen shot
else if((o == UIInterfaceOrientationPortrait && statusBarOrientation == UIInterfaceOrientationLandscapeLeft) ||
(o == UIInterfaceOrientationPortraitUpsideDown && statusBarOrientation == UIInterfaceOrientationLandscapeRight))
{
preTransform = CGAffineTransformTranslate(preTransform, 0, rect.size.height);
preTransform = CGAffineTransformRotate(preTransform, - M_PI_2);
preTransform = CGAffineTransformTranslate(preTransform, CGRectGetMaxY(rect) - screenHeight, -rect.origin.x);
}
else if((o == UIInterfaceOrientationPortrait && statusBarOrientation == UIInterfaceOrientationLandscapeRight) ||
(o == UIInterfaceOrientationPortraitUpsideDown && statusBarOrientation == UIInterfaceOrientationLandscapeLeft))
{
preTransform = CGAffineTransformTranslate(preTransform, 0, rect.size.height);
preTransform = CGAffineTransformRotate(preTransform, M_PI_2);
preTransform = CGAffineTransformTranslate(preTransform, -CGRectGetMaxY(rect), rect.origin.x - screenWidth);
}
else if((o == UIInterfaceOrientationPortrait && statusBarOrientation == UIInterfaceOrientationPortraitUpsideDown) ||
(o == UIInterfaceOrientationPortraitUpsideDown && statusBarOrientation == UIInterfaceOrientationPortrait))
{
preTransform = CGAffineTransformTranslate(preTransform, 0, rect.size.height);
preTransform = CGAffineTransformRotate(preTransform, - M_PI);
preTransform = CGAffineTransformTranslate(preTransform, rect.origin.x - screenWidth, CGRectGetMaxY(rect) - screenHeight);
}
//Handle status bar orientation in landscape left and landscape right screen shot
else if((o == UIInterfaceOrientationLandscapeLeft && statusBarOrientation == UIInterfaceOrientationPortrait) ||
(o == UIInterfaceOrientationLandscapeRight && statusBarOrientation == UIInterfaceOrientationPortraitUpsideDown))
{
preTransform = CGAffineTransformTranslate(preTransform, 0, rect.size.height);
preTransform = CGAffineTransformRotate(preTransform, M_PI_2);
preTransform = CGAffineTransformTranslate(preTransform, -CGRectGetMaxY(rect), rect.origin.x - screenHeight);
}
else if((o == UIInterfaceOrientationLandscapeLeft && statusBarOrientation == UIInterfaceOrientationLandscapeRight) ||
(o == UIInterfaceOrientationLandscapeRight && statusBarOrientation == UIInterfaceOrientationLandscapeLeft))
{
preTransform = CGAffineTransformTranslate(preTransform, 0, rect.size.height);
preTransform = CGAffineTransformRotate(preTransform, M_PI);
preTransform = CGAffineTransformTranslate(preTransform, rect.origin.x - screenHeight, CGRectGetMaxY(rect) - screenWidth);
}
else if((o == UIInterfaceOrientationLandscapeLeft && statusBarOrientation == UIInterfaceOrientationPortraitUpsideDown) ||
(o == UIInterfaceOrientationLandscapeRight && statusBarOrientation == UIInterfaceOrientationPortrait))
{
preTransform = CGAffineTransformTranslate(preTransform, 0, rect.size.height);
preTransform = CGAffineTransformRotate(preTransform, - M_PI_2);
preTransform = CGAffineTransformTranslate(preTransform, CGRectGetMaxY(rect) - screenWidth, -rect.origin.x);
}
// -renderInContext: renders in the coordinate space of the layer,
// so we must first apply the layer's geometry to the graphics context
CGContextSaveGState(context);
// Apply pre transform
CGContextConcatCTM(context, preTransform);
// Center the context around the window's anchor point
CGContextTranslateCTM(context, [statusBarView center].x, [statusBarView center].y);
// Apply the view transform about the anchor point
CGContextConcatCTM(context, [statusBarView transform]);
// Offset by the portion of the bounds left of and above the anchor point
CGContextTranslateCTM(context,
-[statusBarView bounds].size.width * [[statusBarView layer] anchorPoint].x,
-[statusBarView bounds].size.height * [[statusBarView layer] anchorPoint].y);
// Render the layer hierarchy to the current context
if ([statusBarView respondsToSelector:@selector(drawViewHierarchyInRect:afterScreenUpdates:)]) {
[statusBarView drawViewHierarchyInRect:statusBarView.bounds afterScreenUpdates:YES];
} else {
[statusBarView.layer renderInContext:context];
}
// Restore the context
CGContextRestoreGState(context);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.