How to resize or create a thumbnail image from file stream on UWP

时间:2022-07-13 05:13:09

最近在搞Ocr相关的windows universal app, 用到了一些图像处理相关的知识。

涉及到了BitmapDecoder/BitmapEncoder/IRandomAccessStream等类,下面总结了IRandomAccessStream的一些扩展方法,以后还会慢慢加上其他常用的。

 public static class RandomAccessStreamExtension
{
/// <summary>
/// Retrieves an adjusted thumbnail image with the specified file stream.
/// </summary>
/// <param name="inputStream">The input stream.</param>
/// <param name="requestedSize">The requested size, in pixels.</param>
/// <returns></returns>
public static async Task<byte[]> GetThumbnailAsync(this IRandomAccessStream inputStream, uint requestedSize)
{
if (inputStream == null)
return null; var decoder = await BitmapDecoder.CreateAsync(inputStream);
var originalPixelWidth = decoder.PixelWidth;
var originalPixelHeight = decoder.PixelHeight;
if (originalPixelWidth < requestedSize || originalPixelHeight < requestedSize)
{
return await inputStream.GetBytesAsync();
} using (var outputStream = new InMemoryRandomAccessStream())
{
var encoder = await BitmapEncoder.CreateForTranscodingAsync(outputStream, decoder);
double widthRatio = (double)requestedSize / originalPixelWidth;
double heightRatio = (double)requestedSize / originalPixelHeight; uint aspectHeight = requestedSize;
uint aspectWidth = requestedSize; if (originalPixelWidth > originalPixelHeight)
{
aspectWidth = (uint)(heightRatio * originalPixelWidth);
}
else
{
aspectHeight = (uint)(widthRatio * originalPixelHeight);
} encoder.BitmapTransform.InterpolationMode = BitmapInterpolationMode.Linear;
encoder.BitmapTransform.ScaledHeight = aspectHeight;
encoder.BitmapTransform.ScaledWidth = aspectWidth;
await encoder.FlushAsync(); return await outputStream.GetBytesAsync();
}
} /// <summary>
/// Retrieves byte array from the input stream.
/// </summary>
/// <param name="stream">The input stream.</param>
/// <returns></returns>
public static async Task<byte[]> GetBytesAsync(this IRandomAccessStream stream)
{
var bytes = new byte[stream.Size];
using (var reader = new DataReader(stream.GetInputStreamAt()))
{
await reader.LoadAsync((uint)stream.Size);
reader.ReadBytes(bytes);
return bytes;
}
} /// <summary>
/// Retrieves the pixel data.
/// </summary>
/// <param name="stream">The input stream.</param>
/// <returns></returns>
public static async Task<byte[]> GetPixelDataAsync(this IRandomAccessStream stream)
{
var decoder = await BitmapDecoder.CreateAsync(stream);
var provider = await decoder.GetPixelDataAsync();
return provider.DetachPixelData();
}
}

Byte array 转 IRandomAccessStream。

下面的两个方法用到了 WindowsRuntimeBufferExtensions 和 WindowsRuntimeStreamExtensions两个类的扩展方法。

需要引用System.Runtime.InteropServices.WindowsRuntime 和 System.IO 命名空间

public static IRandomAccessStream AsRandomAccessStream(this byte[] bytes)
{
return bytes.AsBuffer().AsStream().AsRandomAccessStream();
} public static IRandomAccessStream ConvertToRandomAccessStream(this byte[] bytes)
{
var stream = new MemoryStream(bytes);
return stream.AsRandomAccessStream();
}