• 【WP8】图片压缩处理


    最近在做图片上传功能,类似于微信朋友圈的功能,现在的手机像素都比较高,手机上的图片一般都比较大(几M),对于大图,在上传之前,我们需要对图片进行压缩(分辨率和质量),再上传到服务器,以减少网路流量传输

      实现思路:

        判断图片是否大于指定的大小

          否:原图上传

          是:通过BitmapImage检测出图片分辨率,然后将分辨率限制在1200*1200分辨率以内(保持宽高比),然后通过SaveJpeg方法写入到流中

      笔者测试,绝大部分图片处理后都能控制在300kb以内(部分超过一点)

    using System;
    using System.IO;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Media.Imaging;
    
    namespace XTuOne.Utility.Helpers
    {
        public class ImageHelper
        {
            /// <summary>
            /// 压缩图片
            /// </summary>
            /// <param name="imageStream">输入</param>
            /// <param name="quality">压缩质量</param>
            /// <param name="maxKb">最大大小(单位kb)只供参考</param>
            public static Stream CompressImage(Stream imageStream, int quality = 80, int maxKb = 300)
            {
                if (imageStream.Length > 300*1024)
                {
                    if (imageStream.CanSeek)
                    {
                        imageStream.Seek(0, SeekOrigin.Begin);
                    }
                    var bitmapImage = new BitmapImage();
                    bitmapImage.SetSource(imageStream);
                    var writeableBitmap = new WriteableBitmap(bitmapImage);
                    var tempStreamm = new MemoryStream();
                    var size = GetSize(bitmapImage.PixelWidth, bitmapImage.PixelHeight);
                    writeableBitmap.SaveJpeg(tempStreamm, (int)size.Width, (int)size.Height, 0, 80);
                    return tempStreamm;
                }
                return imageStream;
            }
    
    
            private static Size GetSize(Size size)
            {
                return GetSize(size.Width, size.Height);
            }
    
    
            private static Size GetSize(double width, double height)
            {
                if (width > height)
                {
                    if (width > 1200)
                    {
                        return new Size(1200, Convert.ToInt32(height * 1200 / width));
                    }
                    return new Size(width, height);
                }
                else
                {
                    if (height > 1200)
                    {
                        return new Size(Convert.ToInt32(width * 1200 / height), 1200);
                    }
                    return new Size(width, height);
                }
            }
        }
    }

     测试中发现一个问题:如果图片太大(5000*5000)的话,BitmapImage读取出来的宽高会被限制在4096*4096之内,如果超过4096,则取4096,保持宽高比,所以如果图片过大,通过BitmapImage是无法获取到图片的真实分辨率的

    下面演示读取SavePicture文件夹中的图片,并进行压缩

            var library = new MediaLibrary();
            foreach (var savedPicture in library.SavedPictures)
            {
                using (var stream = savedPicture.GetImage())
                {
                    using (var tempStream = ImageHelper.CompressImage(stream))
                    {
                        Debug.WriteLine("图片压缩前大小:{0:f2}kb, 图片压缩后大小:{1:f2}kb", stream.Length/1024.0,
                            tempStream.Length/1024.0);
                    }
                    GC.Collect();
                }
            }

    注意:对图片的处理(特别是比较大的图片)很容易造成内存不足的情况(笔者在测试的时候,处理到第三张图片(比较大的图片5-10M)的时候就会出现内存不足的情况)

      所以在使用的时候,没用的Stream应该及时释放掉(using),如果有多张图片需要处理

      为了防止内存不足造成异常,可以通过延迟处理,在处理完一张图片后,等待100毫秒,然后继续

            //延迟0.1秒
            await Task.Delay(100);
  • 相关阅读:
    学习python第四天——列表方法
    昨天休息了一天,今天补上。列表学习
    第二天学习——字符串的方法
    mongodb
    linux学习篇(一)
    mysql优化
    linux服务
    vue配置服务器
    photoshop学习
    关于视图
  • 原文地址:https://www.cnblogs.com/bomo/p/3854350.html
Copyright © 2020-2023  润新知