Search code examples
androidbitmapxamarin.androidscreenshot

Monodroid Taking Screenshots out of memory


So I'm trying to create a function that will essentially take a screenshot of the current app activity and display it on screen before sharing however it runs out of memory when it gets to the screen that I'm using to display the screenshot before getting to the point of sharing.

// image naming and path  to include sd card  appending name you choose for file
Java.IO.File dir = new Java.IO.File(Android.OS.Environment.GetExternalStoragePublicDirectory(Android.OS.Environment.DirectoryPictures), "ScreenShots");

if (!dir.Exists())
    dir.Mkdirs();

// create bitmap screen capture
Bitmap bitmap;
View v1 = act.RootView;
v1.DrawingCacheEnabled = true;
bitmap = Bitmap.CreateBitmap(v1.DrawingCache);
v1.DrawingCacheEnabled = false;

string date = DateTime.Now.ToString();

date = date.Replace('/', '-');

Java.IO.File _file = new Java.IO.File(dir, from + date + ".png");
try
{
    using (var stream = System.IO.File.Create(_file.AbsolutePath))
    {
        bitmap.Compress(Android.Graphics.Bitmap.CompressFormat.Png, 100, stream);
        stream.Flush();
        stream.Close();
    }
    bitmap.Dispose();
    v1.Dispose();
}
catch (Java.IO.FileNotFoundException e)
{
    // TODO Auto-generated catch block
    e.PrintStackTrace();
}
catch (Java.IO.IOException e)
{
    // TODO Auto-generated catch block
    e.PrintStackTrace();
}

I'm trying to find a good way of doing this without sacrificing too much of the quality. Any help with be appreciated=]

UPDATE: I tried doing this opposed to the above with no luck either.

View v1 = act.RootView;
v1.DrawingCacheQuality = DrawingCacheQuality.Low;
v1.DrawingCacheEnabled = true;
Bitmap bitmap = Bitmap.CreateScaledBitmap(v1.GetDrawingCache(true),720,1280,false);
v1.DrawingCacheEnabled = false;
v1.DestroyDrawingCache();
v1.Dispose();

Solution

  • I ended up using:

    // create bitmap screen capture
    View v1 = act.RootView;
    Bitmap bitmap = Bitmap.CreateBitmap(720,1280,Bitmap.Config.Argb8888);
    Canvas can = new Canvas(bitmap);
    v1.Draw(can);
    

    Rather than my updated code. This helped get the screen shot that I needed and kept the memory usage down.