Search code examples
c#windows-runtimewindows-store-appsvisual-studio-2015resize-image

How to resize an image with c# WinRT


No more weeks ago, I've started developing my first windows app metro with Visual Studio 2015. I've noticed that some topics are not easy to find clear information.

I'm trying to resizing (reduce) an image that I have saved previously on file system, and then saving it to another folder.

I've found this thread where they are talking about this. I've adapted the code that they shared but the result image is not acceptable for me. Because, I can see that the result of image seems to be "pixel points", specially on details of image. I don't know how to discribe the result image... Like using the old Paint Brush application, when we change the size image.

What I'm doing wrong? Why it happens?

I've thought using a NuGet package as alternative, to do more easy this work. In this case, exists some nice NuGet package for this task and is capable to work in c# Visual Studio 2015?

I'm going to share my code function:

Note: the new dimensions are proportional on original image, and I'm working with PNG images.

     public async static Task<bool> ResizeImage(Windows.Storage.StorageFile sourceFile, Windows.Storage.StorageFile destinationFile, int newWidth, int newHeight, int dpi)
{
    try
    {
        using (var sourceStream = await sourceFile.OpenAsync(FileAccessMode.Read))
        {
            Windows.Graphics.Imaging.BitmapDecoder decoder = await Windows.Graphics.Imaging.BitmapDecoder.CreateAsync(sourceStream);
            Windows.Graphics.Imaging.BitmapTransform transform = new Windows.Graphics.Imaging.BitmapTransform() { ScaledHeight = Convert.ToUInt32(newHeight), ScaledWidth = Convert.ToUInt32(newWidth) };
            Windows.Graphics.Imaging.PixelDataProvider pixelData = await decoder.GetPixelDataAsync(
                Windows.Graphics.Imaging.BitmapPixelFormat.Rgba8,
                BitmapAlphaMode.Straight,
                transform,
                ExifOrientationMode.RespectExifOrientation,
                ColorManagementMode.DoNotColorManage);

            using (var destinationStream = await destinationFile.OpenAsync(FileAccessMode.ReadWrite))
            {
                BitmapEncoder encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.PngEncoderId, destinationStream);
                encoder.SetPixelData(BitmapPixelFormat.Rgba8, BitmapAlphaMode.Premultiplied, Convert.ToUInt32(newWidth), Convert.ToUInt32(newHeight), Convert.ToUInt32(dpi), Convert.ToUInt32(dpi), pixelData.DetachPixelData());
                await encoder.FlushAsync();
            }
        }
    }
    catch (Exception ex)
    {
        ModuleLog.WriteError(ex.ToString());
        return false;
    }

    return true;
}

NOTE: I'm trying to reduce the size of image. For example, I have a original file image 100 x 100 pixels and I want to obtain an file image of 50 x 50 pixels.


Solution

  • I think that I have found the solution.

    I have added this line in my function:

    transform.InterpolationMode = BitmapInterpolationMode.Fant;
    

    The BitmapTransform has the InterpolationMode property, which you can specify the type of interpolation that we want to use when it resizes a image.

    Here you can see all possibilities.

    In my case, I have noticed that using the "Fant" interpolation is the best to get the best image results.