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();
        }

 

posted @ 2017-06-30 17:32  supperwu  阅读(287)  评论(0编辑  收藏  举报