title: iOS Screenshot as System.Drawing.Bitmap (Xamarin) from Background App
body: <p>For a <strong>private app</strong> (=not to be published on any appstore) on a <strong>jailbroken iOS-Device</strong> I need to take screenshots of the entire screen from being sent to the background.</p>
  
  <p>Similar questions have been posted</p>
  
  <ul>
  <li><a href="https://stackoverflow.com/questions/8548894/ios-is-it-possible-to-take-screenshots-while-running-as-a-background-task">iOS: Is it possible to take screenshots while running as a background task?</a> which concluded that it would be impossible on non-jailbroken devices due to iOS's security sandbox</li>
  <li><a href="https://stackoverflow.com/questions/37085142/how-to-take-screenshots-of-running-iphone-from-background-app">How to take screenshots of running iPhone from background app?</a> is yet pending, but also seems to target non-jailbroken devices</li>
  <li><a href="https://stackoverflow.com/questions/33369014/how-to-take-screenshot-of-entire-screen-on-a-jailbroken-ios-device">How to take screenshot of entire screen on a Jailbroken iOS Device?</a> (and somewhat similar <a href="https://stackoverflow.com/questions/13338416/jailbroken-ios-taking-screenshot-from-background-app">jailbroken iOS taking screenshot from background app</a> ) seems to be close to what I am looking for, but  the code is written in Objective C and makes use of a mysterious private function <em>_UICreateScreenUIImage()</em> of which I don't know in which module it is defined (so I don't know how to declare it as an external function). Also the screenshot is returned as a UIImage (see <a href="http://developer.xamarin.com/api/type/MonoTouch.UIKit.UIImage/" rel="nofollow noreferrer">http://developer.xamarin.com/api/type/MonoTouch.UIKit.UIImage/</a> ) which I yet don't know how to convert to a System.Drawing.Bitmap (see <a href="https://developer.xamarin.com/api/type/System.Drawing.Bitmap/" rel="nofollow noreferrer">https://developer.xamarin.com/api/type/System.Drawing.Bitmap/</a> ).</li>
  </ul>
  
  <p>The following is a post of my code. I am looking for help with the implementation of <code>private System.Drawing.Bitmap ShootScreen()</code></p>
  
  <pre><code>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&lt;Bitmap&gt; _q;                   // Queue to store the Screenshots
  
          #region Interface
          /// &lt;summary&gt;
          /// Creates a Screenshooter
          /// &lt;/summary&gt;
          /// &lt;param name="intervalMS"&gt;Defines every how many MS a screenshot should be taken&lt;/param&gt;
          public ScreenshooterThread(Int32 intervalMS = 200)
          {
              _intervalMS = intervalMS;
          }
  
          /// &lt;summary&gt;
          /// Starts taking Screenshots
          /// &lt;/summary&gt;
          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();
              }
          }
  
          /// &lt;summary&gt;
          /// Stops taking Screenshots
          /// &lt;/summary&gt;
          public void Stop()
          {
              if (!this.IsRunning) return; if (this.IsTerminating) return;
  
              lock(this)
              {
                  _terminate = true;
              }
          }
  
          /// &lt;summary&gt;
          /// Determines whether the Thread is currently running
          /// &lt;/summary&gt;
          public Boolean IsRunning
          {
              get
              {
                  if (_t == null) return false;
  
                  return _t.IsAlive;
              }
          }
          /// &lt;summary&gt;
          /// Determines whether Thread-Termination has been invoked
          /// &lt;/summary&gt;
          public Boolean IsTerminating
          {
              get
              {
                  return _terminate;
              }
          }
  
          /// &lt;summary&gt;
          /// Get a Screenshot from the Queue. Returns null if none available
          /// &lt;/summary&gt;
          public Bitmap Deqeue()
          {
              lock(_q)
              {
                  if (_q.Count &lt; 1) return null;
                  return _q.Dequeue();
              }
          }
  
          #endregion
  
          #region Implementation Details
          /// &lt;summary&gt;
          /// Add a Screenshot to the Queue
          /// &lt;/summary&gt;
          private void Enqueue(Bitmap b)
          {
              lock(_q)
              {
                  _q.Enqueue(b);
              }
          }
  
          /// &lt;summary&gt;
          /// Task-Implementation while running
          /// &lt;/summary&gt;
          private void DoWork()
          {
              while(!_terminate)
              {
                  if (_intervalMS &gt; 0) Thread.Sleep(_intervalMS);
  
                  this.Enqueue(this.ShootScreen());
              }
  
              this.CleanUp();
          }
  
          /// &lt;summary&gt;
          /// Takes a Screenshot of the device even if the app is in the Background
          /// &lt;/summary&gt;
          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();
          }
          /// &lt;summary&gt;
          /// Preparing for next launch
          /// &lt;/summary&gt;
          private void CleanUp()
          {
              lock(this)
              {
                  _terminate = false;
                  _t = null;
              }
          }
          #endregion
      }
  }
  </code></pre>
  
  <p>PS: The screenshots need to be a <code>System.Drawing.Bitmap</code> because I need to perform Pixelwise operations on it afterwards</p>
  
  <p><strong>EDIT 1</strong></p>
  
  <p>Upon further investigation I found on <a href="http://sharpmobilecode.com/introduction-to-xamarin-what-it-is-what-it-isnt/" rel="nofollow noreferrer">http://sharpmobilecode.com/introduction-to-xamarin-what-it-is-what-it-isnt/</a> the following paragraph</p>
  
  <blockquote>
    <p>For example, let’s say you have existing C# code that uses
    System.Drawing.Bitmap. It’s a common library you wrote that multiple
    Desktop apps reference. A possible method looks something like this:</p>
  
  <pre><code>using System.Drawing; 
  
  public Bitmap GetBitmapFromCache(string fileName) 
  { 
     return (Bitmap) Image.FromFile(fileName); 
  }    
  </code></pre>
    
    <p>If you were to compile this method in a Xamarin.iOS or Xamarin.Android app,you would get a compile error.  Huh?  Upon
    further investigation, you would see that <code>System.Drawing.Bitmap</code> and
    <code>System.Drawing.Image</code> are not define.  What!?!?  That’s valid C#
    syntax!  Upon further investigation, you only see a few classes in
    <code>System.Drawing</code> are actually defined (RectangleF, PointF, etc).  Where
    the heck is Bitmap and Image?  Well, there is a good reason these
    classes are not implemented in the Mono Framework.  It’s because they
    are not cross platform compatible.</p>
    
    <p>What does that mean exactly?  Let’s take a look at the System.Drawing
    documentation on MSDN.  It states, “The System.Drawing namespace
    provides access to GDI+ basic graphics functionality.”.  What is GDI+?
    GDI+ (Graphics Device Interface) is a graphics library (Win32) that is
    specific to the Windows Operating System.  So underneath the hood of a
    System.Drawing.Bitmap, is a Win32 implementation that ties into the
    Windows Desktop/Server Operating systems.    That means
    System.Drawing.Bitmap and System.Drawing.Image are platform dependent,
    and only work on Windows Desktop/Server apps.  You will not be able to
    use these classes on iOS app, Android apps, or even Windows Phone
    apps.  So how can you use this current C# code in an iOS or Android
    app?  With a slight modification like this:</p>
  
  <pre><code>public byte[] GetBitmapFromCache(string fileName) 
  { 
      return File.ReadAllBytes(fileName); 
  } 
  </code></pre>
    
    <p>iOS and Android have no concept of GDI+ bitmap
    (System.Drawing.Bitmap), however, each platform knows how to convert
    an array of bytes into their own implementation of a bitmap.  Using
    iOS, you can create a UIImage from an array of bytes, and in Android
    you can create an Android.Graphics.Bitmap from that same array.</p>
  </blockquote>