最近在搞Ocr相關的windows universal app, 用到了一些圖像處理相關的知識。windows
涉及到了BitmapDecoder/BitmapEncoder/IRandomAccessStream等類,下面總結了IRandomAccessStream的一些擴展方法,之後還會慢慢加上其餘經常使用的。app
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。dom
下面的兩個方法用到了 WindowsRuntimeBufferExtensions 和 WindowsRuntimeStreamExtensions兩個類的擴展方法。async
須要引用System.Runtime.InteropServices.WindowsRuntime 和 System.IO 命名空間ide
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(); }