How to resize or create a thumbnail image from file stream on UWP
最近在搞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(0))) { 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(); }