圖片加載時間緩慢問題API


一、背景 

     最近段時間,開發寫值工具項目中,出現圖片加載問題API,響應時間緩慢;為了優化圖片加載問題,我進行圖片壓縮方法,然后API的圖片加載還是慢,最終在自己無意中亂寫找到了根本的原因。

 

二、問題

    優化圖片加載問題

 

三、原因

 1. 在API中,圖片轉換byte[ ]方法,用BMP的格式圖片導致的API圖片加載很慢;

returnImage.Save(mstream2, System.Drawing.Imaging.ImageFormat.Bmp);

2. BMP 不支持壓縮,這會造成文件非常大

 

四、解決方法

1. 壓縮高質量圖片

 ① 這個壓縮圖片方法加載更快,

 //無損壓縮圖片
        public Image GetImageThumbnail(Image image, double scaleFactor = 0.3)
        {
            using (image)
            {
                var newWidth = (int)(image.Width * scaleFactor);
                var newHeight = (int)(image.Height * scaleFactor);
                var thumbnailImg = new Bitmap(newWidth, newHeight);
                var thumbGraph = Graphics.FromImage(thumbnailImg);
                thumbGraph.CompositingQuality = CompositingQuality.HighQuality;
                thumbGraph.SmoothingMode = SmoothingMode.HighQuality;
                thumbGraph.InterpolationMode = InterpolationMode.HighQualityBicubic;
                var imageRectangle = new Rectangle(0, 0, newWidth, newHeight);
                thumbGraph.DrawImage(image, imageRectangle);
                return thumbnailImg;
            }
        }

 

② 壓縮圖片方法比①慢很多

 /// <summary>
        /// 無損壓縮圖片
        /// </summary>
        /// <param name="sFile">原圖片地址</param>
        /// <param name="dFile">壓縮后保存圖片地址</param>
        /// <param name="flag">壓縮質量(數字越小壓縮率越高)1-100</param>
        /// <param name="size">壓縮后圖片的最大大小</param>
        /// <param name="sfsc">是否是第一次調用</param>
        /// <returns></returns>
        public  Image CompressImage(Image iSource, Stream stream, int flag = 90, int size = 300, bool sfsc = true)
        {
            //Image iSource = Image.FromFile(sFile);
            ImageFormat tFormat = iSource.RawFormat;
            ////如果是第一次調用,原始圖像的大小小於要壓縮的大小,則直接復制文件,並且返回true
            //FileInfo firstFileInfo = new FileInfo(sFile);
            //if (sfsc == true && firstFileInfo.Length < size * 1024)
            //{
            //    firstFileInfo.CopyTo(dFile);
            //    return true;
            //}

            int dHeight = iSource.Height / 2;
            int dWidth = iSource.Width / 2;
            int sW = 0, sH = 0;
            //按比例縮放
            Size tem_size = new Size(iSource.Width, iSource.Height);
            if (tem_size.Width > dHeight || tem_size.Width > dWidth)
            {
                if ((tem_size.Width * dHeight) > (tem_size.Width * dWidth))
                {
                    sW = dWidth;
                    sH = (dWidth * tem_size.Height) / tem_size.Width;
                }
                else
                {
                    sH = dHeight;
                    sW = (tem_size.Width * dHeight) / tem_size.Height;
                }
            }
            else
            {
                sW = tem_size.Width;
                sH = tem_size.Height;
            }

            var ob = new Bitmap(dWidth, dHeight);
            Graphics g = Graphics.FromImage(ob);

            g.Clear(Color.WhiteSmoke);
            g.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
            g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
            g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;

            g.DrawImage(iSource, new Rectangle((dWidth - sW) / 2, (dHeight - sH) / 2, sW, sH), 0, 0, iSource.Width, iSource.Height, GraphicsUnit.Pixel);

            g.Dispose();

            //以下代碼為保存圖片時,設置壓縮質量
            EncoderParameters ep = new EncoderParameters();
            long[] qy = new long[1];
            qy[0] = flag;//設置壓縮的比例1-100
            EncoderParameter eParam = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, qy);
            ep.Param[0] = eParam;

            try
            {
                ImageCodecInfo[] arrayICI = ImageCodecInfo.GetImageEncoders();
                ImageCodecInfo jpegICIinfo = null;
                for (int x = 0; x < arrayICI.Length; x++)
                {
                    if (arrayICI[x].FormatDescription.Equals("JPEG"))
                    {
                        jpegICIinfo = arrayICI[x];
                        break;
                    }
                }
                if (jpegICIinfo != null)
                {
                    ob.Save(stream, jpegICIinfo, ep);//dFile是壓縮后的新路徑

                    ///FileInfo fi = new FileInfo();
                    //if (fi.Length > 1024 * size)
                    //{
                    //    flag = flag - 10;
                    //    CompressImage(iSource, stream, flag, size, false);
                    //}
                }
                else
                {
                    ob.Save(stream, tFormat);
                }
                //return true; 
                return ob;
            }
            catch
            {
                return ob;
            }
            //finally
            //{
            //    iSource.Dispose();
            //    //ob.Dispose();
            //}
        }
View Code

 

2. API中,用JPEG的格式

  //二進制轉換圖片的方法
            MemoryStream mstream = new MemoryStream(assetinfor.imagedate);            
Image imadate = Image.FromStream(mstream); var returnImage = assetinfor.GetImageThumbnail(imadate);
//圖片再轉換byte[]方法 MemoryStream mstream2 = new MemoryStream(); //var returnImage = assetinfor.CompressImage(imadate, mstream2); //returnImage.Save(mstream2, System.Drawing.Imaging.ImageFormat.Bmp); returnImage.Save(mstream2, System.Drawing.Imaging.ImageFormat.Jpeg); byte[] byData = new Byte[mstream2.Length]; mstream2.Position = 0; mstream2.Read(byData, 0, byData.Length); mstream2.Close(); this.images = Convert.ToBase64String(byData);
//釋放資源 mstream.Dispose(); mstream2.Dispose(); } /// <summary> /// 圖片 /// </summary> public string images { get; set; }

 

3. JPEG的圖片格式支持高級壓縮

 

五、C#中image和byte[ ]的互相轉換

1、如圖所示,項目中所應用到的轉換;

 

 2. image和byte[ ]的互相轉換

 

①     參數是圖片路徑:返回Byte[]類型

//參數是圖片的路徑

        public byte[] GetPictureData(string imagePath)

        {
            FileStream fs = new FileStream(imagePath, FileMode.Open);

            byte[] byteData = new byte[fs.Length];

            fs.Read(byteData, 0, byteData.Length);

            fs.Close();

            return byteData;
        } 

 

②      參數類型是Image對象,返回Byte[]類型

 

  //將Image轉換成流數據,並保存為byte[] 

        public byte[] PhotoImageInsert(System.Drawing.Image imgPhoto)

        {
            MemoryStream mstream = new MemoryStream();

            imgPhoto.Save(mstream, System.Drawing.Imaging.ImageFormat.Bmp);

            byte[] byData = new Byte[mstream.Length];

            mstream.Position = 0;

            mstream.Read(byData, 0, byData.Length); mstream.Close();

            return byData;
        }

 

③      參數是Byte[]類型,返回值是Image對象

  public System.Drawing.Image ReturnPhoto(byte[] streamByte)
        {
            System.IO.MemoryStream ms = new System.IO.MemoryStream(streamByte);
            System.Drawing.Image img = System.Drawing.Image.FromStream(ms);
            return img;
        }
      

④  參數是Byte[] 類型,沒有返回值(ASP.NET輸出圖片)

 

public void WritePhoto(byte[] streamByte)

        {
            // Response.ContentType 的默認值為默認值為“text/html”

            Response.ContentType = "image/GIF";

            //圖片輸出的類型有: image/GIF     image/JPEG

            Response.BinaryWrite(streamByte);
}

 

 

六、GIF,JPG, BMP和JPEG的圖片有什么區別

①     BMP:Windows 位圖

詳細說明:Windows 位圖可以用任何顏色深度(從黑白到 24 位顏色)存儲單個光柵圖像。Windows 位圖文件格式與其他 Microsoft Windows 程序兼容,BMP 文件適用於 Windows 中的牆紙。

缺點:BMP 不支持壓縮,這會造成文件非常大,BMP 文件不受 Web 瀏覽器支持。

優點:BMP 支持 1 位到 24 位顏色深度,BMP 格式與現有 Windows 程序(尤其是較舊的程序)廣泛兼容。

 

②     PNG:可移植網絡圖形 

詳細說明:PNG 圖片以任何顏色深度存儲單個光柵圖像。PNG 是與平台無關的格式。

優點:PNG 支持高級別無損耗壓縮; PNG 支持 alpha 通道透明度; PNG 支持伽瑪校正; PNG 支持交錯; PNG 接受最新的 Web 瀏覽器支持。 

缺點: 較舊的瀏覽器和程序可能不支持 PNG 文件。 作為 Internet 文件格式,與 JPEG 的有損耗壓縮相比,PNG 提供的壓縮量較少。 作為 Internet 文件格式,PNG 對多圖像文件或動畫文件不提供任何支持。GIF 格式支持多圖像文件和動畫文件。

 

③     JPEG:聯合攝影專家組 

詳細說明:JPEG 圖片以 24 位顏色存儲單個光柵圖像。JPEG 是與平台無關的格式,支持最高級別的壓縮,不過,這種壓縮是有損耗的。漸近式 JPEG 文件支持交錯。可以提高或降低 JPEG 文件壓縮的級別。但是,文件大小是以圖像質量為代價的。壓縮比率可以高達 100:1。(JPEG 格式可在 10:1 到 20:1 的比率下輕松地壓縮文件,而圖片質量不會下降。)JPEG 壓縮可以很好地處理寫實攝影作品。

優點:攝影作品或寫實作品支持高級壓縮。 利用可變的壓縮比可以控制文件大小。 支持交錯(對於漸近式 JPEG 文件)。 JPEG 廣泛支持 Internet 標准。 

缺點:有損耗壓縮會使原始圖片數據質量下降。 當您編輯和重新保存 JPEG 文件時,JPEG 會混合原始圖片數據的質量下降。這種下降是累積性的。 JPEG 不適用於所含顏色很少、具有大塊顏色相近的區域或亮度差異十分明顯的較簡單的圖片

 

④    GIF:圖形交換格式 

詳細說明:GIF 圖片以 8 位顏色或 256 色存儲單個光柵圖像數據或多個光柵圖像數據。GIF 圖   片支持透明度、壓縮、交錯和多圖像圖片(動畫 GIF)。GIF 透明度不是 alpha 通道透明度,不能支持半透明效果。GIF 壓縮是 LZW 壓縮,壓縮比大概為 3:1。GIF 文件規范的 GIF89a 版本中支持動畫 GIF。

優點: GIF 廣泛支持 Internet 標准。 支持無損耗壓縮和透明度。 動畫 GIF 很流行,易於使用許多 GIF 動畫程序創建。 

缺點: GIF 只支持 256 色調色板,因此,詳細的圖片和寫實攝影圖像會丟失顏色信息,而看起來卻是經過調色的。 在大多數情況下,無損耗壓縮效果不如 JPEG 格式或 PNG 格式。 GIF 支持有限的透明度,沒有半透明效果或褪色效果(例如,alpha 通道透明度提供的效果)。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM