Convert StorageFile to a BitmapImage in Universal Windows Apps

We have already seen how to convert a WritableBitmap to a StorageFile in Universal Windows apps.

A StorageFile can be converted to a BitmapImage using the following function.

public class ImageUtils
{
    public static async Task<BitmapImage> StorageFileToBitmapImage(StorageFile savedStorageFile)
    {
        using (IRandomAccessStream fileStream = await savedStorageFile.OpenAsync(Windows.Storage.FileAccessMode.Read))
        {
            BitmapImage bitmapImage = new BitmapImage();
            bitmapImage.DecodePixelHeight = 100;
            bitmapImage.DecodePixelWidth = 100;
            await bitmapImage.SetSourceAsync(fileStream);
            return bitmapImage;
        }
    }
}

To use the function call it as follows.

BitmapImage imageSource= await ImageUtils.StorageFileToBitmapImage(savedStorageFile);

convert a WritableBitmap to a StorageFile in Universal Windows apps

Converting WritableBitmap to StorageFile in Universal Windows Apps

WriteableBitmap is quite useful when an app requires image processing. It provides a BitmapSource, that can be written and manipulated. Ultimately that bitmap source is supplied to an image control of a Windows Store app. We are going to save the WritableBitmap to a StorageFile in our app.

For image encoding WinRT offers the BitmapEncoder class. For image encoding we need to select a BitmapEncoderGuid that is basically a formatted of image, such as JPEG, PNG, TIFF, and so on. It’s actually a unique identifier for each bitmap encoder.

We will first export WriteableBitmap’s pixel buffer into a byte array. Then we will initialize the bitmap encoder with a GUID and destination file stream. Finally we will set the pixel data to a bitmap encoder. Bitmap encoder’s SetPixelData(...) gets various parameters to write the pixels in various ways. Check out the method metadata given below. At last we will have the file ready.

public class ImageUtils
{
    public static async Task<StorageFile> WriteableBitmapToStorageFile(WriteableBitmap WB, FileFormat fileFormat)
    {
        string FileName = "MyFile.";
        Guid BitmapEncoderGuid = BitmapEncoder.JpegEncoderId;
        switch (fileFormat)
        {
            case FileFormat.Jpeg:
                FileName += "jpeg";
                BitmapEncoderGuid = BitmapEncoder.JpegEncoderId;
                break;
            case FileFormat.Png:
                FileName += "png";
                BitmapEncoderGuid = BitmapEncoder.PngEncoderId;
                break;
            case FileFormat.Bmp:
                FileName += "bmp";
                BitmapEncoderGuid = BitmapEncoder.BmpEncoderId;
                break;
            case FileFormat.Tiff:
                FileName += "tiff";
                BitmapEncoderGuid = BitmapEncoder.TiffEncoderId;
                break;
            case FileFormat.Gif:
                FileName += "gif";
                BitmapEncoderGuid = BitmapEncoder.GifEncoderId;
                break;
        }
        var file = await Windows.Storage.ApplicationData.Current.TemporaryFolder
    .CreateFileAsync(FileName, CreationCollisionOption.GenerateUniqueName);
        using (IRandomAccessStream stream = await file.OpenAsync(FileAccessMode.ReadWrite))
        {
            BitmapEncoder encoder = await BitmapEncoder.CreateAsync(BitmapEncoderGuid, stream);
            Stream pixelStream = WB.PixelBuffer.AsStream();
            byte[] pixels = new byte[pixelStream.Length];
            await pixelStream.ReadAsync(pixels, 0, pixels.Length);
            encoder.SetPixelData(BitmapPixelFormat.Bgra8, BitmapAlphaMode.Ignore,
                      (uint)WB.PixelWidth,
                      (uint)WB.PixelHeight,
                      96.0,
                      96.0,
                      pixels);
            await encoder.FlushAsync();
        }
        return file;
    }
    public enum FileFormat
    {
        Jpeg,
        Png,
        Bmp,
        Tiff,
        Gif
    }
}

Don’t forget to add the namespace System.Runtime.InteropServices.WindowsRuntime.

To use the converter call it as follows.

StorageFile savedStorageFile= await ImageUtils.WriteableBitmapToStorageFile(ImageCropper.CroppedImage, ImageUtils.FileFormat.Png);