Storing a BitmapImage in LocalFolder - UWP

2020-07-18 03:21发布

问题:

I'm trying to store a BitmapImage to the filesystem using C# on UWP. The image is downloaded from Facebook using the graph api and returned as a BitmapImage. That part works, and to retrieve the image (once I can store it, tested with pictures just dropped in the local folder) I'm using the following code:

public static async Task<BitmapImage> GetProfilePicture(string userId){
    BitmapImage profilePicture = new BitmapImage(); 

    StorageFolder pictureFolder = await
                  ApplicationData.Current.LocalFolder.GetFolderAsync("ProfilePictures");
    StorageFile pictureFile = await pictureFolder.GetFileAsync(userId + ".jpg");
    IRandomAccessStream stream = await pictureFile.OpenAsync(FileAccessMode.Read);
    profilePicture.SetSource(stream);

    return profilePicture;   

This works as well, so what I would want is to simply do the opposite. The preferred result would look like this:

public static async void SaveBitmapToFile(BitmapImage  image, userId){
    StorageFolder pictureFolder = await
        ApplicationData.Current.LocalFolder.CreateFolderAsync(
            "ProfilePictures",CreationCollisionOption.OpenIfExists);

       //save bitmap to pictureFolder with name userId.jpg

}

I've searched far and wide trying to find a solution, but I can't seem to find any for the UWP platform. How would a go about saving the Bitmap to file? The extension doesn't have to be .jpg if it would be easier to use another extension.

回答1:

It would be easier if you used a WriteableBitmap. For example, the first method would then be:

public static async Task<WriteableBitmap> GetProfilePictureAsync(string userId)
{
    StorageFolder pictureFolder = await ApplicationData.Current.LocalFolder.GetFolderAsync("ProfilePictures");
    StorageFile pictureFile = await pictureFolder.GetFileAsync(userId + ".jpg");

    using (IRandomAccessStream stream = await pictureFile .OpenAsync(FileAccessMode.Read))
    {
        BitmapDecoder decoder = await BitmapDecoder.CreateAsync(stream);
        WriteableBitmap bmp = new WriteableBitmap((int)decoder.PixelWidth, (int)decoder.PixelHeight);

        await bmp.SetSourceAsync(stream);

        return bmp;
    }
}

Then you could do:

public static async Task SaveBitmapToFileAsync(WriteableBitmap image, userId)
{
    StorageFolder pictureFolder = await ApplicationData.Current.LocalFolder.CreateFolderAsync("ProfilePictures",CreationCollisionOption.OpenIfExists);
    var file = await pictureFolder.CreateFileAsync(userId + ".jpg", CreationCollisionOption.ReplaceExisting);

    using (var stream = await file.OpenStreamForWriteAsync())
    {
        BitmapEncoder encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.JpegEncoderId, stream.AsRandomAccessStream());
        var pixelStream = image.PixelBuffer.AsStream();
        byte[] pixels = new byte[bmp.PixelBuffer.Length];

        await pixelStream.ReadAsync(pixels, 0, pixels.Length);

        encoder.SetPixelData(BitmapPixelFormat.Bgra8, BitmapAlphaMode.Ignore, (uint)image.PixelWidth, (uint)image.PixelHeight, 96, 96, pixels);

        await encoder.FlushAsync();
    }
}


标签: c# bitmap uwp