对于 jailbroken iOS-Device 上的私有应用(=不在任何appstore上发布),我需要将整个屏幕的屏幕截图发送到背景。
已发布类似问题
以下是我的代码的帖子。我正在寻求有关private System.Drawing.Bitmap ShootScreen()
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Threading;
namespace StackOverflowSnippets
{
public sealed class ScreenshooterThread
{
private Thread _t = null; // Thread-Object: Execution-Helper
private Boolean _terminate = false; // Stop current execution?
private Int32 _intervalMS = 0; // Take Screenshots every ? MS
private Queue<Bitmap> _q; // Queue to store the Screenshots
#region Interface
/// <summary>
/// Creates a Screenshooter
/// </summary>
/// <param name="intervalMS">Defines every how many MS a screenshot should be taken</param>
public ScreenshooterThread(Int32 intervalMS = 200)
{
_intervalMS = intervalMS;
}
/// <summary>
/// Starts taking Screenshots
/// </summary>
public void Run()
{
if(this.IsRunning || this.IsTerminating)
{
throw new InvalidOperationException("ScreenshooterThread is currently running or terminating");
}
lock (this)
{
_terminate = false;
_t = new Thread(this.DoWork);
_t.Start();
}
}
/// <summary>
/// Stops taking Screenshots
/// </summary>
public void Stop()
{
if (!this.IsRunning) return; if (this.IsTerminating) return;
lock(this)
{
_terminate = true;
}
}
/// <summary>
/// Determines whether the Thread is currently running
/// </summary>
public Boolean IsRunning
{
get
{
if (_t == null) return false;
return _t.IsAlive;
}
}
/// <summary>
/// Determines whether Thread-Termination has been invoked
/// </summary>
public Boolean IsTerminating
{
get
{
return _terminate;
}
}
/// <summary>
/// Get a Screenshot from the Queue. Returns null if none available
/// </summary>
public Bitmap Deqeue()
{
lock(_q)
{
if (_q.Count < 1) return null;
return _q.Dequeue();
}
}
#endregion
#region Implementation Details
/// <summary>
/// Add a Screenshot to the Queue
/// </summary>
private void Enqueue(Bitmap b)
{
lock(_q)
{
_q.Enqueue(b);
}
}
/// <summary>
/// Task-Implementation while running
/// </summary>
private void DoWork()
{
while(!_terminate)
{
if (_intervalMS > 0) Thread.Sleep(_intervalMS);
this.Enqueue(this.ShootScreen());
}
this.CleanUp();
}
/// <summary>
/// Takes a Screenshot of the device even if the app is in the Background
/// </summary>
private System.Drawing.Bitmap ShootScreen()
{
// System.Drawing.Bitmap supported by Xamarin
// https://developer.xamarin.com/api/type/System.Drawing.Bitmap/
// Method in ObjC: https://stackoverflow.com/questions/33369014/how-to-take-screenshot-of-entire-screen-on-a-jailbroken-ios-device
throw new NotImplementedException();
}
/// <summary>
/// Preparing for next launch
/// </summary>
private void CleanUp()
{
lock(this)
{
_terminate = false;
_t = null;
}
}
#endregion
}
}
PS:屏幕截图必须是System.Drawing.Bitmap
,因为我之后需要对它执行Pixelwise操作
编辑1
经过进一步调查,我在http://sharpmobilecode.com/introduction-to-xamarin-what-it-is-what-it-isnt/上找到了以下段落
例如,假设您使用的是现有的C#代码 System.Drawing.Bitmap。这是一个你写的多个常见的库 桌面应用参考。一种可能的方法如下所示:
using System.Drawing; public Bitmap GetBitmapFromCache(string fileName) { return (Bitmap) Image.FromFile(fileName); }
如果您要在Xamarin.iOS或Xamarin.Android应用程序中编译此方法,则会出现编译错误。咦?上 进一步调查,你会看到
System.Drawing.Bitmap
和。{System.Drawing.Image
未定义。什么!?!?这是有效的C# 句法!经过进一步调查,你只能看到几个班级 实际定义了System.Drawing
(RectangleF,PointF等)。哪里 哎呀是Bitmap和Image?嗯,这是有充分理由的 类在Mono Framework中没有实现。这是因为他们 不是跨平台兼容的。这究竟是什么意思?我们来看看System.Drawing MSDN上的文档。它声明,“System.Drawing命名空间 提供对GDI +基本图形功能的访问。“什么是GDI +? GDI +(图形设备接口)是一个图形库(Win32) 特定于Windows操作系统。所以在一个引擎盖下面 System.Drawing.Bitmap是一个绑定到的Win32实现 Windows桌面/服务器操作系统。这意味着 System.Drawing.Bitmap和System.Drawing.Image是平台相关的, 并且只适用于Windows桌面/服务器应用程序。你将无法做到 在iOS应用,Android应用甚至Windows Phone上使用这些类 应用。那么如何在iOS或Android中使用当前的C#代码呢? 应用程序吗?稍作修改:
public byte[] GetBitmapFromCache(string fileName) { return File.ReadAllBytes(fileName); }
iOS和Android没有GDI +位图的概念 (System.Drawing.Bitmap),但是,每个平台都知道如何转换 将一个字节数组放入自己的位图实现中。运用 iOS,你可以从一个字节数组和Android中创建一个UIImage 你可以从同一个数组创建一个Android.Graphics.Bitmap。
答案 0 :(得分:0)
如http://sharpmobilecode.com/introduction-to-xamarin-what-it-is-what-it-isnt/所述,无法创建System.Drawing.Bitmap
,因为System.Drawing
命名空间可以访问特定于Windows操作系统的GDI +基础图形功能,因此根本无法使用在iOS上。
然而,可以将屏幕截图创建为UIImage
,如下所示
How to take screenshot of entire screen on a Jailbroken iOS Device?显示,存在一个返回所需屏幕截图的私有函数_UICreateScreenUIImage(void)
。要访问此函数,必须声明它
using System.Runtime.InteropServices;
using ObjCRuntime;
[DLLImport(/*ObjCRuntime.*/Constants.UIKitLibrary)]
extern static IntPtr _UICreateScreenUIImage();
调用时,返回的IntPtr指向本机UIImage,需要将其包装到托管对象中,由Runtime.GetNSObject(IntPtr)
IntPtr ptr = _UICreateScreenUIImage();
UIImage uiimg = Runtime.GetNSObject(ptr) as UIImage;
生成的uiimg
包含屏幕截图
附图包含有关如何创建屏幕截图并将其另存为.jpeg
当应用在后台时,屏幕截图可能会是什么样子