How to Resize Image in C# Winrt/Winmd

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



Leave a reply



Submit