国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

【問題帖】壓縮圖片大小至指定Kb以下

2019-11-14 16:53:04
字體:
來源:轉載
供稿:網友

  像PS,QQ影像等都有該功能,將圖片大小壓縮至指定kb以下。

  我也來山寨一把,到目前為止,控制圖片的大小,平時的解決方案通過分辨率和質量來控制的。

  假定最后壓縮的大小是100kb,那么在保證不大于100kb的前提下,圖片質量盡可能高。圖片質量越高,圖片占用大小就越大。但是大小與質量的關系,沒有一個固定的公式,如y= nx 之類的,而且我也試過將Win7系統的圖片收藏夾的圖,每一張保存10次,從質量為10,遞增到100,發現只能得出之前的結論,圖片質量高,占用大小就大。

  既然這樣,那只能找到滿足1ookb大小的最合適的質量參數了。這里使用了二分法來查找。

        /// <summary>        /// 壓縮圖片至n Kb以下        /// </summary>        /// <param name="img">圖片</param>        /// <param name="format">圖片格式</param>        /// <param name="targetLen">壓縮后大小</param>        /// <param name="srcLen">原始大小</param>        /// <returns>壓縮后的圖片內存流</returns>        public static MemoryStream Zip(Image img, ImageFormat format, long targetLen, long srcLen = 0)        {            //設置允許大小偏差幅度 默認10kb            const long nearlyLen = 10240;            //返回內存流  如果參數中原圖大小沒有傳遞 則使用內存流讀取            var ms = new MemoryStream();            if (0 == srcLen)            {                img.Save(ms, format);                srcLen = ms.Length;            }            //單位 由Kb轉為byte 若目標大小高于原圖大小,則滿足條件退出            targetLen *= 1024;            if (targetLen >= srcLen)            {                ms.SetLength(0);                ms.Position = 0;                img.Save(ms, format);                return ms;            }            //獲取目標大小最低值            var exitLen = targetLen - nearlyLen;            //初始化質量壓縮參數 圖像 內存流等            var quality = (long)Math.Floor(100.00 * targetLen / srcLen);            var parms = new EncoderParameters(1);            //獲取編碼器信息            ImageCodecInfo formatInfo = null;            var encoders = ImageCodecInfo.GetImageEncoders();            foreach (ImageCodecInfo icf in encoders)            {                if (icf.FormatID == format.Guid)                {                    formatInfo = icf;                    break;                }            }            //使用二分法進行查找 最接近的質量參數            long startQuality = quality;            long endQuality = 100;            quality = (startQuality + endQuality) / 2;            while (true)            {                //設置質量                parms.Param[0] = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, quality);                //清空內存流 然后保存圖片                ms.SetLength(0);                ms.Position = 0;                img.Save(ms, formatInfo, parms);                //若壓縮后大小低于目標大小,則滿足條件退出                if (ms.Length >= exitLen && ms.Length <= targetLen)                {                    break;                }                else if (startQuality >= endQuality) //區間相等無需再次計算                {                    break;                }                else if (ms.Length < exitLen) //壓縮過小,起始質量右移                {                    startQuality = quality;                }                else //壓縮過大 終止質量左移                {                    endQuality = quality;                }                //重新設置質量參數 如果計算出來的質量沒有發生變化,則終止查找。這樣是為了避免重復計算情況{start:16,end:18} 和 {start:16,endQuality:17}                var newQuality = (startQuality + endQuality) / 2;                if (newQuality == quality)                {                    break;                }                quality = newQuality;                Console.WriteLine("start:{0} end:{1} current:{2}", startQuality, endQuality, quality);            }            return ms;        } 

測試過程中發現,每張圖的處理時間差不多為1s。完成需求,倒是沒問題,但總覺得是不是應該有更合適的方案呢,如果有知道的朋友,歡迎提供知了一起探討!

測試代碼下載


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 布尔津县| 柳河县| 广丰县| 东平县| 奇台县| 措美县| 兴仁县| 儋州市| 南投县| 毕节市| 黄石市| 云南省| 洛阳市| 东安县| 垦利县| 湟中县| 兴宁市| 邓州市| 呼伦贝尔市| 科技| 香港| 封丘县| 志丹县| 雷波县| 无极县| 什邡市| 大厂| 通州市| 高邑县| 时尚| 平和县| 友谊县| 洛南县| 北流市| 南乐县| 曲麻莱县| 德化县| 夹江县| 融水| 鄯善县| 义乌市|