前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >win10 uwp 修改图片质量压缩图片

win10 uwp 修改图片质量压缩图片

作者头像
林德熙
发布2019-04-09 10:32:16
1.1K0
发布2019-04-09 10:32:16
举报
文章被收录于专栏:林德熙的博客

本文告诉大家如何在 UWP 通过修改图片的质量减少图片大小,这个方法只支持输出 jpg 文件

通过创建 BitmapEncoder 的时候指定 BitmapPropertySet 可以设置图片的质量,只有对 JPG 格式才能设置图片质量

图片质量的值是从 0 到 1 其中 1 表示质量最好

代码语言:javascript
复制
    var propertySet = new BitmapPropertySet();
    // 图片质量,值范围是 0到1 其中 1 的质量最好
    var qualityValue = new BitmapTypedValue(imageQuality,
        Windows.Foundation.PropertyType.Single);
    propertySet.Add("ImageQuality", qualityValue);
    var encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.JpegEncoderId, imageWriteAbleStream,
        propertySet);

这里的 imageQuality 就是图片质量,这个需要传入

从一个图片文件压缩图片大小的方法可以这样写,创建一个方法传入原图文件,和需要输出的文件,和图片质量

代码语言:javascript
复制
        private async Task<StorageFile> ConvertImageToJpegAsync(StorageFile sourceFile, StorageFile outputFile,
            double imageQuality)

先获取图片大小,这样可以知道压缩了多少,对比原图的文件大小和压缩之后的图片大小

代码语言:javascript
复制
            var sourceFileProperties = await sourceFile.GetBasicPropertiesAsync();
            var fileSize = sourceFileProperties.Size;

获取文件大小更简单的方法是通过 WinRTXamlToolkit 的 StorageItemExtensions.GetSizeAsync 拿到文件大小

读取原图文件,需要先解码原图,然后通过编码的时候修改图片质量

代码语言:javascript
复制
            var imageStream = await sourceFile.OpenReadAsync();

解码的方法是不需要知道图片的格式

代码语言:javascript
复制
                var decoder = await BitmapDecoder.CreateAsync(imageStream);
                var pixelData = await decoder.GetPixelDataAsync();
                var detachedPixelData = pixelData.DetachPixelData();

打开输出文件,进行编码

代码语言:javascript
复制
                var imageWriteAbleStream = await outputFile.OpenAsync(FileAccessMode.ReadWrite);

在创建编码的时候设置图片质量

代码语言:javascript
复制
    var propertySet = new BitmapPropertySet();
    // 图片质量,值范围是 0到1 其中 1 的质量最好
    var qualityValue = new BitmapTypedValue(imageQuality,
        Windows.Foundation.PropertyType.Single);
    propertySet.Add("ImageQuality", qualityValue);
    var encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.JpegEncoderId, imageWriteAbleStream,
        propertySet);

将编码写入到文件

代码语言:javascript
复制
    encoder.SetPixelData(decoder.BitmapPixelFormat, decoder.BitmapAlphaMode, decoder.OrientedPixelWidth,
        decoder.OrientedPixelHeight, decoder.DpiX, decoder.DpiY, detachedPixelData);
    await encoder.FlushAsync();
    await imageWriteAbleStream.FlushAsync();

拿到压缩只有的文件的大小,对比一下

代码语言:javascript
复制
    var jpegImageSize = imageWriteAbleStream.Size;
    // 欢迎访问我博客 https://blog.lindexi.com/ 里面有大量 UWP WPF 博客
    Debug.WriteLine($"压缩之后比压缩前的文件小{fileSize - jpegImageSize}");

这个压缩图片的方法的代码虽然看起来很多,但是看起来还是很简单先打开原来的图片文件对原图进行解密然后输出到新的文件

代码语言:javascript
复制
        /// <summary>
        /// 将原来的图片转换图片质量和压缩质量
        /// </summary>
        /// <param name="sourceFile">原来的图片</param>
        /// <param name="outputFile">输出的文件</param>
        /// <param name="imageQuality">图片质量,取值范围是 0 到 1 其中 1 的质量最好,这个值设置只对 jpg 图片有效</param>
        /// <returns></returns>
        private async Task<StorageFile> ConvertImageToJpegAsync(StorageFile sourceFile, StorageFile outputFile,
            double imageQuality)
        {
            var sourceFileProperties = await sourceFile.GetBasicPropertiesAsync();
            var fileSize = sourceFileProperties.Size;
            var imageStream = await sourceFile.OpenReadAsync();
            using (imageStream)
            {
                var decoder = await BitmapDecoder.CreateAsync(imageStream);
                var pixelData = await decoder.GetPixelDataAsync();
                var detachedPixelData = pixelData.DetachPixelData();
                var imageWriteAbleStream = await outputFile.OpenAsync(FileAccessMode.ReadWrite);
                using (imageWriteAbleStream)
                {
                    var propertySet = new BitmapPropertySet();
                    // 图片质量,值范围是 0到1 其中 1 的质量最好
                    var qualityValue = new BitmapTypedValue(imageQuality,
                        Windows.Foundation.PropertyType.Single);
                    propertySet.Add("ImageQuality", qualityValue);
                    var encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.JpegEncoderId, imageWriteAbleStream,
                        propertySet);
                    //key thing here is to use decoder.OrientedPixelWidth and decoder.OrientedPixelHeight otherwise you will get garbled image on devices on some photos with orientation in metadata
                    encoder.SetPixelData(decoder.BitmapPixelFormat, decoder.BitmapAlphaMode, decoder.OrientedPixelWidth,
                        decoder.OrientedPixelHeight, decoder.DpiX, decoder.DpiY, detachedPixelData);
                    await encoder.FlushAsync();
                    await imageWriteAbleStream.FlushAsync();
                    var jpegImageSize = imageWriteAbleStream.Size;
                    // 欢迎访问我博客 https://blog.lindexi.com/ 里面有大量 UWP WPF 博客
                    Debug.WriteLine($"压缩之后比压缩前的文件小{fileSize - jpegImageSize}");
                }
            }

            return outputFile;
        }

于是下面写一个测试的程序

在界面创建一个按钮

代码语言:javascript
复制
        <Button Content="压缩图片" HorizontalAlignment="Center" VerticalAlignment="Center" Click="Button_OnClick" />

在按钮拿到一个文件,然后在自己的临时文件夹里面创建输出文件,如果真的需要用这个程序压缩图片那么请让用户再选一个文件

代码语言:javascript
复制
        private async void Button_OnClick(object sender, RoutedEventArgs e)
        {
            var pick = new FileOpenPicker();
            pick.FileTypeFilter.Add(".jpg");
            var file = await pick.PickSingleFileAsync();

            if (file != null)
            {
                await ConvertImageToJpegAsync(file,
                    await ApplicationData.Current.TemporaryFolder.CreateFileAsync("lindexi"),
                    0.75);
            }
        }

现在尝试运行代码,点击界面的按钮,就可以看到点击按钮选择

代码放在 github

这个代码参考了Alex Sorokoletov的代码

How to convert image to JPEG and specify quality parameter in UWP C# XAML

BitmapEncoder options reference - Windows UWP applications

Create, edit, and save bitmap images - Windows UWP applications


本文会经常更新,请阅读原文: https://lindexi.gitee.io/post/win10-uwp-%E4%BF%AE%E6%94%B9%E5%9B%BE%E7%89%87%E8%B4%A8%E9%87%8F%E5%8E%8B%E7%BC%A9%E5%9B%BE%E7%89%87.html ,以避免陈旧错误知识的误导,同时有更好的阅读体验。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档