Screen capture to media library instead of isolated storage

Screen capture to media library instead of isolated storage

One of the things REALLY missing on Windows Phone is the ability to take screenshots inside of your application, because emulator often doesn’t let you do what you like. One of the things is that when you want to load and display data such as photos and music, it only gives you a few shots available, but there’s no way for you to use your own photos or your own music. In this article, I’ll edit one class for screen capturing which you can use in your application, and show you how to save it to the media library of the phone.

I found that one of the best classes, and the best code for taking screenshots on Windows Phone on Jeff Wilcox blog. He wrote a class called ScreenCapture.cs released under Apache 2 license

// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

I felt it would be easier is to save the image to the media library of the phone. Instead, it originally saves the screenshot to IsolatedStorage of the application, and does it every X seconds, where X is the number you give to the method ScreenShots.BeginTakingPictures(). If you don’t give a parameter to the function, it takes 2 seconds as a default value.

To save to your media library, simply add the reference to Microsoft.Xna.Framework to your projects references and add the following line at the beginning of the class

using Microsoft.Xna.Framework.Media;  

and then instead of saving to isolated storage like this:

using (var st = _isf.CreateFile(filename))  
{     
    st.Write(bb, 0, bb.Length);
}

use MediaLibrary class:

using (var lib = new MediaLibrary())  
{
    lib.SavePicture(filename, bb);
}

Now, this method can fill your media libary and your phone with unnecessary images. I, on the other hand, like to be in control of that, so instead of using dispatcher timer, I will recommend a method which should be removed before publishing to Marketplace, but you can use it for your internal testing and screenshot taking.

Whenever you want to take a screenshot, just override OnDoubleTap event handler on your page. Just write:

protected override void OnDoubleTap(GestureEventArgs e)  
{
    ScreenShots.TakePicture();
    base.OnDoubleTap(e);
}

If you are using double tap somewhere in your app and this is inconvenient, use something else to trigger the TakePicture method. The TakePicture method uses the code from the ScreenShots class, which now looks like this:

    public static class ScreenShots
    {
        public static void TakePicture()
        {

            var ui = Application.Current.RootVisual;
            try
            {
                if (ui != null)
                {
                    FrameworkElement fe = ui as FrameworkElement;
                    if (fe != null)
                    {
                        var width = fe.ActualWidth;
                        var height = fe.ActualHeight;

                        WriteableBitmap wb = new WriteableBitmap(ui,
                            new TranslateTransform());
                        wb.Render(ui, new TranslateTransform());
                        byte[] bb = EncodeToJpeg(wb);

                        string filename = "screenshots"
                            + DateTime.Now.Ticks
                            .ToString(CultureInfo.InvariantCulture)
                            + ".jpg";

                        using (var lib = new MediaLibrary())
                        {
                            lib.SavePicture(filename, bb);
                        }

                        Debug.WriteLine("Saved screenshot to " + filename);
                    }
                }
            }
            catch (Exception)
            {
            }
        }

        public static byte[] EncodeToJpeg(WriteableBitmap wb)
        {
            using (MemoryStream stream = new MemoryStream())
            {
                wb.SaveJpeg(
                    stream,
                    wb.PixelWidth,
                    wb.PixelHeight,
                    0,
                    85);
                return stream.ToArray();
            }
        }
    }

I hope this will help you take screenshots! I took one to demonstrate the results, and I used the app from my previous blog post.

screenshots 634563717655260000

Of course, I used the code above with Jeff’s permission on Twitter! :)

image

Enjoy! :)

Igor Ralic

igor ralic

View Comments
Microsoft Certified Solutions Developer: Windows Store Apps in C#