zoukankan      html  css  js  c++  java
  • 图片加载时间缓慢问题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 通道透明度提供的效果)。

  • 相关阅读:
    第三周学习进度条
    软件工程个人作业02
    构建之法阅读笔记02
    学习进度条
    构建之法阅读笔记01
    软件工程个人作业01
    构建之法粗读
    第一次作业
    动手动脑接口与继承
    大道至简第七章第八章
  • 原文地址:https://www.cnblogs.com/qy1234/p/11139160.html
Copyright © 2011-2022 走看看