图片加载时间缓慢问题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(, , 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 = , int size = , 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 / ;
int dWidth = iSource.Width / ;
int sW = , sH = ;
//按比例缩放
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) / , (dHeight - sH) / , sW, sH), , , iSource.Width, iSource.Height, GraphicsUnit.Pixel); g.Dispose(); //以下代码为保存图片时,设置压缩质量
EncoderParameters ep = new EncoderParameters();
long[] qy = new long[];
qy[] = flag;//设置压缩的比例1-100
EncoderParameter eParam = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, qy);
ep.Param[] = eParam; try
{
ImageCodecInfo[] arrayICI = ImageCodecInfo.GetImageEncoders();
ImageCodecInfo jpegICIinfo = null;
for (int x = ; 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 = ;
mstream2.Read(byData, , 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, , 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 = ;
mstream.Read(byData, , 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 通道透明度提供的效果)。
图片加载时间缓慢问题API的更多相关文章
- Android中常见的图片加载框架
图片加载涉及到图片的缓存.图片的处理.图片的显示等.而随着市面上手机设备的硬件水平飞速发展,对图片的显示要求越来越高,稍微处理不好就会造成内存溢出等问题.很多软件厂家的通用做法就是借用第三方的框架进行 ...
- Android之图片加载框架Fresco基本使用(二)
PS:最近看到很多人都开始写年终总结了,时间过得飞快,又到年底了,又老了一岁. 学习内容: 1.进度条 2.缩放 3.ControllerBuilder,ControllerListener,Post ...
- Android 三大图片加载框架的对比——ImageLoader,Picasso,Glide
一.ImageLaoder介绍 << Universal ImageLoader 是很早开源的图片缓存,在早期被很多应用使用 多线程下载图片,图片可以来源于网络,文件系统,项目文件夹ass ...
- Android图片加载库的理解
前言 这是“基础自测”系列的第三篇文章,以Android开发需要熟悉的20个技术点为切入点,本篇重点讲讲Android中的ImageLoader这个库的一些理解,在Android上最让人头疼是 ...
- Android图片加载库:最全面的Picasso讲解
前言 上文已经对当今 Android主流的图片加载库 进行了全面介绍 & 对比 如果你还没阅读,我建议你先移步这里阅读 今天我们来学习其中一个Android主流的图片加载库的使用 - Pica ...
- fackbook的Fresco (FaceBook推出的Android图片加载库-Fresco)
[Android开发经验]FaceBook推出的Android图片加载库-Fresco 欢迎关注ndroid-tech-frontier开源项目,定期翻译国外Android优质的技术.开源库.软件 ...
- Fresco-FaceBook推出的Android图片加载库
在Android设备上面,快速高效的显示图片是极为重要的.过去的几年里,我们在如何高效的存储图像这方面遇到了很多问题.图片太大,但是手机的内存却很小.每一个像素的R.G.B和alpha通道总共要占用4 ...
- Google图片加载库Glide的简单封装GlideUtils
Google图片加载库Glide的简单封装GlideUtils 因为项目里用的Glide的地方比较多,所有简单的封装了以下,其实也没什么,就是写了个工具类,但是还是要把基础说下 Glide的Githu ...
- Android图片加载库Fresco
在Android设备上面,快速高效的显示图片是极为重要的.过去的几年里,我们在如何高效的存储图像这方面遇到了很多问题.图片太大,但是手机的内存却很小.每一个像素的R.G.B和alpha通道总共要占用4 ...
随机推荐
- WPF 圆角textbox
原文:WPF 圆角textbox 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/a771948524/article/details/9245965 ...
- 【HLSL学习笔记】WPF Shader Effect Library算法解读之[BandedSwirl]
原文:[HLSL学习笔记]WPF Shader Effect Library算法解读之[BandedSwirl] 因工作原因,需要在Silverlight中使用Pixel Shader技术,这对于我来 ...
- Android 动画具体解释Frame动画 (Drawable Animation)
Frame动画像gif画画,通过一些静态的图片,以实现动画效果. Android sdk该AnimationDrawable就是专门针对Frame动画,当然Frame动画也可在java代码或者xml中 ...
- WPF - 本质:数据和行为
原文:WPF - 本质:数据和行为 如果自己来做一个UI框架,我们会首先关注哪些方面?我想UI框架主要处理的一定包括两个主要层次的内容,一个是数据展现,另一个就是数据操作,所以UI框架必须能够接收各种 ...
- 高性能mysql笔记 第一章 mysql架构
1.1 mysql逻辑结构 第一层: 负责连接处理,授权认证,安全等事情 第二层:负责mysql的大部分核心功能 ,查询解析,分析,优化,缓存和所有的内置函数,所有跨存储引擎的功能都在这一层实现,, ...
- Bootstrap 屏幕类型
/* 超小屏幕(手机,小于 768px) */ /* 没有任何媒体查询相关的代码,因为这在 Bootstrap 中是默认的(还记得 Bootstrap 是移动设备优先的吗?) */ /* 小屏幕(平板 ...
- MVC linq执行顺序
- WPF中类似使用tab键功能,可以向上向下定位
原文:WPF中类似使用tab键功能,可以向上向下定位 private void tbYyrs_KeyUp(object sender, KeyEventArgs e) { UIElement elem ...
- 那些证书相关的玩意儿(SSL,X.509,PEM,DER,CRT,CER,KEY,CSR,P12等)(使用OpenSSL的命令行)
之前没接触过证书加密的话,对证书相关的这些概念真是感觉挺棘手的,因为一下子来了一大堆新名词,看起来像是另一个领域的东西,而不是我们所熟悉的编程领域的那些东西,起码我个人感觉如此,且很长时间都没怎么搞懂 ...
- win10 uwp ApplicationView
原文:win10 uwp ApplicationView 本文和大家介绍一个重要的类,他可以用来设置窗口,如设置启动大小,设置是否允许截图,是否进入全屏,所有和窗口有关的,都可以在他这里设置. 可以使 ...