I have created a function that will take as a parameter a StorageFile
and return a WriteableBitmap
. I use this data type so that I can later encode the image into a base64 string.
My concern is with the intermediary BitmapImage
that I create to get the original dimensions. Any other improvements would be welcomed as well.
Also, it should be noted that this is Windows 10 Universal code, so I am unable to use the System.Drawing
libraries.
public static async Task<WriteableBitmap> ScaledWImage(StorageFile file, int maxWidth, int maxHeight)
{
WriteableBitmap newImage;
using (var fileStream = await file.OpenReadAsync())
{
var bitmap = new BitmapImage();
bitmap.SetSource(fileStream);
var origHeight = bitmap.PixelHeight;
var origWidth = bitmap.PixelWidth;
var ratioX = maxWidth / (float)origWidth;
var ratioY = maxHeight / (float)origHeight;
var ratio = Math.Min(ratioX, ratioY);
var newHeight = (int)(origHeight * ratio);
var newWidth = (int)(origWidth * ratio);
if (ratio > 1)
{
newHeight = origHeight;
newWidth = origWidth;
}
newImage = new WriteableBitmap(newWidth, newHeight);
fileStream.Seek(0);
var decoder = await BitmapDecoder.CreateAsync(fileStream);
// Scale image to appropriate size
var transform = new BitmapTransform()
{
ScaledWidth = Convert.ToUInt32(newImage.PixelWidth),
ScaledHeight = Convert.ToUInt32(newImage.PixelHeight)
};
var pixelData = await decoder.GetPixelDataAsync(
BitmapPixelFormat.Bgra8, // WriteableBitmap uses BGRA format
BitmapAlphaMode.Straight,
transform,
ExifOrientationMode.IgnoreExifOrientation, // This sample ignores Exif orientation
ColorManagementMode.DoNotColorManage
);
// An array containing the decoded image data, which could be modified before being displayed
var sourcePixels = pixelData.DetachPixelData();
// Open a stream to copy the image contents to the WriteableBitmap's pixel buffer
using (var stream = newImage.PixelBuffer.AsStream())
{
await stream.WriteAsync(sourcePixels, 0, sourcePixels.Length);
}
}
return newImage;
}
This code is adapted from a Microsoft sample found here.