How to resize Image in C# WinRT/winmd?
Example of how to scale and crop taken from here:
async private void BitmapTransformTest()
{
// hard coded image location
string filePath = "C:\\Users\\Public\\Pictures\\Sample Pictures\\fantasy-dragons-wallpaper.jpg";
StorageFile file = await StorageFile.GetFileFromPathAsync(filePath);
if (file == null)
return;
// create a stream from the file and decode the image
var fileStream = await file.OpenAsync(Windows.Storage.FileAccessMode.Read);
BitmapDecoder decoder = await BitmapDecoder.CreateAsync(fileStream);
// create a new stream and encoder for the new image
InMemoryRandomAccessStream ras = new InMemoryRandomAccessStream();
BitmapEncoder enc = await BitmapEncoder.CreateForTranscodingAsync(ras, decoder);
// convert the entire bitmap to a 100px by 100px bitmap
enc.BitmapTransform.ScaledHeight = 100;
enc.BitmapTransform.ScaledWidth = 100;
BitmapBounds bounds = new BitmapBounds();
bounds.Height = 50;
bounds.Width = 50;
bounds.X = 50;
bounds.Y = 50;
enc.BitmapTransform.Bounds = bounds;
// write out to the stream
try
{
await enc.FlushAsync();
}
catch (Exception ex)
{
string s = ex.ToString();
}
// render the stream to the screen
BitmapImage bImg = new BitmapImage();
bImg.SetSource(ras);
img.Source = bImg; // image element in xaml
}
How to resize an image with c# WinRT
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.
Images pixelate when resized in WinRT
I had the same problem but found a very neat solution for this. The keyword is DecodePixelHeight
<Image Width="100" Height="100" Stretch="UniformToFill">
<Image.Source>
<BitmapImage DecodePixelWidth="100" UriSource="{Binding ImagePath}" />
</Image.Source>
</Image>
Credit goes to: http://www.geekchamp.com/forums/windows-8-development/resizing-an-image-without-losing-any-quality-in-windows-store-app#forum-post-386827
How to edit and save photo in Windows Store App?
Mateusz will something like this inside your foreach loop work I am not sure
ras.Seek(0);
fileStream.Seek(0);
fileStream.Size = 0;
await RandomAccessStream.CopyAsync(ras, fileStream);
fileStream.Dispose();
ras.Dispose();
How to correctly resize/recompress image
The following solution was provided by StefanDK in this edit:
It seems that the problem with my former solution was that I did not properly close the streams and that I did not have the correct settings.
Basically the solution incorporates elements from these articles:
- How to resize Image in C# WinRT/winmd?
- https://stackoverflow.com/questions/15481126/windows-store-app-resize-bitmapimage-c-sharp
- http://msdn.microsoft.com/en-us/library/windows/apps/jj709942.aspx
- http://msdn.microsoft.com/en-us/library/windows/apps/hh465076.aspx
From the main part of the code I make these calls for each image that needs downloading, resizing and compressing:
Main code
Note that I am well aware of the "not best practice" in assigning a string value and then setting it again. This is prototype code that has not been fine-tuned yet.
var img = await ArticleStorage.GetLocalImageAsync(src);
img = await ArticleStorage.ResizeAndCompressLocalImage(img);
Source code of the methods in ArticleStorage
public const string CachedImagesFolderFullPath = "ms-appdata:///local/cache/";
public const string CachedImagesFolderEndFolderPath = "cache";
public const string OfflinePhotoImgPath = "ms-appx:///Assets/OfflinePhoto.png";
public const int MaximumColumnWidth = 700;
public static async Task<string> GetLocalImageAsync(string internetUri)
{
if (string.IsNullOrEmpty(internetUri))
{
return null;
}
// Show default image if local folder does not exist
var localFolder = ApplicationData.Current.LocalFolder;
if (localFolder == null)
{
return OfflinePhotoImgPath;
}
// Default to offline photo
string src = OfflinePhotoImgPath;
try
{
using (var response = await HttpWebRequest.CreateHttp(internetUri)
.GetResponseAsync())
{
using (var stream = response.GetResponseStream())
{
// New random filename (e.g. x53fjtje.jpg)
string fileName = string.Format("{0}.jpg",
Path.GetFileNameWithoutExtension(Path.GetRandomFileName()));
var imageFolder = await localFolder.CreateFolderAsync(
CachedImagesFolderEndFolderPath,
CreationCollisionOption.OpenIfExists);
var file = await imageFolder.CreateFileAsync(fileName,
CreationCollisionOption.ReplaceExisting);
// Copy bytes from stream to local file
// without changing any file information
using (var filestream = await file.OpenStreamForWriteAsync())
{
await stream.CopyToAsync(filestream);
// Send back the local path to the image
// (including 'ms-appdata:///local/cache/')
return string.Format(CachedImagesFolderFullPath + "{0}",
fileName);
}
}
}
}
catch (Exception)
{
// Is implicitly handled with the setting
// of the initilized value of src
}
// If not succesfull, return the default offline image
return src;
}
public static async Task<string> ResizeAndCompressLocalImage(string imgSrc)
{
// Remove 'ms-appdata:///local/cache/' from the path ...
string sourcepathShort = imgSrc.Replace(
CachedImagesFolderFullPath,
string.Empty);
// Get the cached images folder
var folder = await ApplicationData.Current
.LocalFolder
.GetFolderAsync(
CachedImagesFolderEndFolderPath);
// Get a new random name (e.g. '555jkdhr5.jpg')
var targetPath = string.Format("{0}.jpg",
Path.GetFileNameWithoutExtension(
Path.GetRandomFileName()));
// Retrieve source and create target file
var sourceFile = await folder.GetFileAsync(sourcepathShort);
var targetFile = await folder.CreateFileAsync(targetPath);
using (var sourceFileStream = await sourceFile.OpenAsync(
Windows.Storage.FileAccessMode.Read))
{
using (var destFileStream = await targetFile.OpenAsync(
FileAccessMode.ReadWrite))
{
// Prepare decoding of the source image
BitmapDecoder decoder = await BitmapDecoder.CreateAsync(
sourceFileStream);
// Find out if image needs resizing
double proportionWidth = (double)decoder.PixelWidth /
LayoutDimensions.MaximumColumnWidth;
double proportionImage = decoder.PixelHeight /
(double)decoder.PixelWidth;
// Get the new sizes of the image whether it is the same or should be resized
var newWidth = proportionWidth > 1 ?
(uint)(MaximumColumnWidth) :
decoder.PixelWidth;
var newHeight = proportionWidth > 1 ?
(uint)(MaximumColumnWidth * proportionImage) :
decoder.PixelHeight;
// Prepare set of properties for the bitmap
BitmapPropertySet propertySet = new BitmapPropertySet();
// Set ImageQuality
BitmapTypedValue qualityValue = new BitmapTypedValue(0.75,
PropertyType.Single);
propertySet.Add("ImageQuality", qualityValue);
//BitmapEncoder enc = await BitmapEncoder.CreateForTranscodingAsync(
destFileStream, decoder);
BitmapEncoder enc = await BitmapEncoder.CreateAsync(
BitmapEncoder.JpegEncoderId,
destFileStream, propertySet);
// Set the new dimensions
enc.BitmapTransform.ScaledHeight = newHeight;
enc.BitmapTransform.ScaledWidth = newWidth;
// Get image data from the source image
PixelDataProvider pixelData = await decoder.GetPixelDataAsync();
// Copy in all pixel data from source to target
enc.SetPixelData(
decoder.BitmapPixelFormat,
decoder.BitmapAlphaMode,
decoder.PixelWidth,
decoder.PixelHeight,
decoder.DpiX,
decoder.DpiY,
pixelData.DetachPixelData()
);
// Make the encoder process the image
await enc.FlushAsync();
// Write everything to the filestream
await destFileStream.FlushAsync();
}
}
try
{
// Delete the source file
await sourceFile.DeleteAsync();
}
catch(Exception)
{
}
// Return the new path
// including "ms-appdata:///local/cache/"
return string.Format(CachedImagesFolderFullPath + "{0}",
targetPath);
}
How to compress the image to 70% in the Windows Store apps?
Please find the link to compressed the image in windows store app.
http://msdn.microsoft.com/en-us/library/windows/apps/jj218354.aspx
Code sample is given in Javascript, which can be easily changed to c#.
This should work.
Related Topics
Is the C# Compiler Smart Enough to Optimize This Code
C# Array.Findallindexof Which Findall Indexof
Async and Await - Difference Between Console, Windows Forms and ASP.NET
ASP.NET MVC Route to Catch All *.Aspx Requests
When Should I Choose Inheritance Over an Interface When Designing C# Class Libraries
How to Prevent Synchronous Continuations on a Task
Change Connection String & Reload App.Config at Run Time
How to Create Migrations After Upgrading to ASP.NET Core 2.0
How to Register a .Net Dll File in the Gac
Parent Control Mouse Enter/Leave Events with Child Controls
Use Dependency Injection in Static Class
Overloaded Method-Group Argument Confuses Overload Resolution
Trying to Debug Windows Store App from Dump Files
How to Get a Character in a String by Index
Should I Take Ilogger, Ilogger<T>, Iloggerfactory or Iloggerprovider for a Library