图片加载时间缓慢问题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();
            //}
        }

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);      }

3. 参考网址:https://www.cnblogs.com/zxk3200/articles/4244132.html

六、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 通道透明度提供的效果)。

原文地址:https://www.cnblogs.com/qy1234/p/11139160.html

时间: 2024-11-05 18:48:06

图片加载时间缓慢问题API的相关文章

iOS开发&gt;学无止境 - 异步图片加载优化与常用开源库分析

作者:罗轩(@luoyibu) 网址:http://www.jianshu.com/p/3b2c95e1404f 1. 网络图片显示大体步骤:   下载图片 图片处理(裁剪,边框等) 写入磁盘 从磁盘读取数据到内核缓冲区 从内核缓冲区复制到用户空间(内存级别拷贝) 解压缩为位图(耗cpu较高) 如果位图数据不是字节对齐的,CoreAnimation会copy一份位图数据并进行字节对齐 CoreAnimation渲染解压缩过的位图 以上4,5,6,7,8步是在UIImageView的setImag

Android中常见的图片加载框架

图片加载涉及到图片的缓存.图片的处理.图片的显示等.而随着市面上手机设备的硬件水平飞速发展,对图片的显示要求越来越高,稍微处理不好就会造成内存溢出等问题.很多软件厂家的通用做法就是借用第三方的框架进行图片加载. 开源框架的源码还是挺复杂的,但使用较为简单.大部分框架其实都差不多,配置稍微麻烦点,但是使用时一般只需要一行,显示方法一般会提供多个重载方法,支持不同需要.这样会减少很不必要的麻烦.同时,第三方框架的使用较为方便,这大大的减少了工作量.提高了开发效率.本文主要介绍四种常用的图片加载框架,

Android之图片加载框架Fresco基本使用(二)

PS:最近看到很多人都开始写年终总结了,时间过得飞快,又到年底了,又老了一岁. 学习内容: 1.进度条 2.缩放 3.ControllerBuilder,ControllerListener,PostProcesser,Image Request 4.渐进式JPEG与动图的显示     最近这两天把Fresco的官方文档算是看了个差不多,就剩下Fresco的基本原理还有结合okHttp等类库如何使用的问题,虽然官方文档给出的功能比较的多,比如说自定义View,缩略图显示等等,这些我也基本就看了个

Android图片加载神器之Fresco,基于各种使用场景的讲解

转载请标明出处:http://blog.csdn.net/android_ls/article/details/53137867 Fresco是Facebook开源Android平台上一个强大的图片加载库,也是迄今为止Android平台上最强大的图片加载库. 优点:相对于其他开源的第三方图片加载库,Fresco拥有更好的内存管理和强大的功能,基本上能满足所有的日常使用场景. 缺点:整体比较大,不过目前的版本已做了拆分,你只需要导入你使用到的功能相关的库.从代码层面来说侵入性太强,体现在要使用它需

FaceBook推出的Android图片加载库-Fresco

FaceBook推出的Android图片加载库-Fresco 原文链接:Introducing Fresco: A new image library for Android 译者 :  ZhaoKaiQiang 校对者: Chaossss 校对者: bboyfeiyu 校对者: BillionWang 状态 :  完成 在Android设备上面,快速高效的显示图片是极为重要的.过去的几年里,我们在如何高效的存储图像这方面遇到了很多问题.图片太大,但是手机的内存却很小.每一个像素的R.G.B和a

Android图片加载库:最全面的Picasso讲解

前言 上文已经对当今 Android主流的图片加载库 进行了全面介绍 & 对比 如果你还没阅读,我建议你先移步这里阅读 今天我们来学习其中一个Android主流的图片加载库的使用 - Picasso 目录 1. 简介 介绍:Picasso,可译为"毕加索",是Android中一个图片加载开源库 大概是因为其使用使用方法简单.优雅所以这样取名 主要作用:实现图片加载 2. 功能特点 2.1 功能列表 从上面可以看出,Picasso不仅实现了图片异步加载的功能,还解决了Androi

Android图片加载库的理解

前言 这是“基础自测”系列的第三篇文章,以Android开发需要熟悉的20个技术点为切入点,本篇重点讲讲Android中的ImageLoader这个库的一些理解,在Android上最让人头疼是从网络中获取图片,显示,回收,任何一个环节有问题都可能直接OOM,当需要加载大量的图片的时候,每当快速滑,有时候会很卡,甚至会因为内存溢出而崩溃.这里讲解的库是:Universal_Image_Loader. 内容目录 ImageLoader设计原理 ImageLoader流程图 ImageLoader的使

详谈高大上的图片加载框架Glide

在Android设备上,加载网络图片一直是一个头疼的问题,因为Android设备种类繁多(当然最主要的是配置),处理的稍不周到轻则应用卡顿,严重者就会出现OOM的,导致程序挂掉.现如今网络上有很多图片库,如 Universal-Image-Loader,Picasso,Fresco,Glide等等.相信列举出的这几个库大家都不陌生,这也是目前最火的图片库了.由于个人的喜好原因(主要是别人介绍说Glide库比较NB),所以就开始研究学习Glide. Glide库和Picasso库有极大的相似性,编

【Android开发经验】FaceBook推出的Android图片加载库-Fresco

欢迎关注ndroid-tech-frontier开源项目,定期翻译国外Android优质的技术.开源库.软件架构设计.测试等文章 原文链接:Introducing Fresco: A new image library for Android 译者 : ZhaoKaiQiang 校对者: Chaossss 校对者: bboyfeiyu 校对者: BillionWang 状态 : 完成 在Android设备上面,快速高效的显示图片是极为重要的.过去的几年里,我们在如何高效的存储图像这方面遇到了很多