返回顶部
首页 > 资讯 > 精选 >怎么在iOS中高效的加载图片
  • 401
分享到

怎么在iOS中高效的加载图片

2023-06-25 11:06:49 401人浏览 独家记忆
摘要

这篇文章主要介绍怎么在iOS中高效的加载图片,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!图片的渲染流程在ioS中使用 UIImage和UIImageView来记载图片,他俩遵守经典的mvc架构,UIImage相当于

这篇文章主要介绍怎么在iOS中高效的加载图片,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!

    图片的渲染流程

    ioS中使用 UIImage和UIImageView来记载图片,他俩遵守经典的mvc架构,UIImage相当于Model,UIImageView相当于View:

    怎么在iOS中高效的加载图片

    UIImage负责加载图片,UIImageView负责渲染图片。

    怎么在iOS中高效的加载图片

    图片的渲染流程分为3个阶段:加载(Load),解码(Decoder)和渲染(Render)

    怎么在iOS中高效的加载图片

    在每个阶段都会有相对应的缓冲区:数据缓冲区(DataBuffer),图像缓冲区(imageBuffer)和帧缓冲区(framebuffer)。

    我们以加载一个图片的尺寸为:2048 px * 1536 px,在磁盘上的大小为:590kb的图片为例,来分析前两个阶段的缓冲区。

    DataBuffer

    DataBuffer只是一种包含一系列字节的缓冲区。通常以某些元数据开头,元数据描述了存储在数据缓冲区中的图像大小,包含图形数据本身,图像数据以某种形式编码 如 JPEG压缩或PNG,这意味着,该字节并不直接描述图像中像素的任何内容。此时的 DataBuffer大小为 590kb。

    SD源码分析

    在SDWEBImage中,图片加载完成后,在 sd_imageFORMatForImageData的方法中,是通过DataBuffer的第一个字节来判断图片的格式的。

    uint8_t c;    [data getBytes:&c length:1];    switch (c) {        case 0xFF:            return SDImageFormatJPEG;        case 0x89:            return SDImageFormatPNG;        case 0x47:            retur SDImageFormatGIF;        case 0x49:        case 0x4D:            return SDImageFormatTIFF;                ......   }

    ImageBuffer

    在图片加载完后,需要将Data Buffer的JPEG,PNG或其他编码的数据,转换为每个像素的图像信息,这个过程,称为Decoder(解码),将像素信息存放在ImageBuffer。

    占用内存大小

    图片占用的内存大小与图像的尺寸有关,与它的文件大小无关,在iOSSRGB显示格式中(4byte空间显示一个像素),如果解析所有的像素,需要 2048 px * 1536 px * 4 byte/px = 10MB的空间,此时的 ImageBuffer的大小为10MB。

    在ImageBuffer解析完后,提交给frameBuffer进行渲染显示。

    总的来说,图片加载过程和消耗的内存如下图所示:

    怎么在iOS中高效的加载图片

    Xcode测试

    在Xcode工程中,当push新页面的时候,只加载一个图片。

    加载前内存值:

    怎么在iOS中高效的加载图片

    加载后内存值:

    怎么在iOS中高效的加载图片

    大多数情况下,我们并不需要如此高精度的显示图片,占用了这么多的内存,能否减少加载图片时占用的内存值呢?

    如何减少图像占用内存

    向下采样

    在苹果官方文档中,建议我们使用向下采样(Downsampleing)的技术,来加载图片,减少ImageBuffer的大小。

    怎么在iOS中高效的加载图片

    方法如下:

    func downsample(imageAt imageURL: URL, to pointSize:CGSize, scale:CGFloat) ->UIImage {    let imageSourcesOptions = [kCGImageSourceShouldCache: false] as CFDictionary    let imageSource = CGImageSourceCreateWithURL(imageURL as CFURL, imageSourcesOptions)!    let maxDimensionInPixels = max(pointSize.width, pointSize.height) * scale    let downsampleOptions = [            kCGImageSourceCreateThumbnailFromImageAlways: true,            kCGImageSourceShouldCacheImmediately: true,            kCGImageSourceCreateThumbnailWithTransform: true,            kCGImageSourceThumbnailMaxPixelSize:maxDimensionInPixels        ] as CFDictionary    let downsampledImage = CGImageSourceCreateThumbnailAtIndex(imageSource, 0, downsampleOptions)!        return UIImage(cgImage: downsampledImage) }

    我们来测试一下:

       let imageStr = Bundle.main.path(forResource: "view_site.jpeg", ofType: nil)   let imageURL =  URL(string: "file://" + (imageStr ?? ""))   guard let imgURL = imageURL else {       return   }   imageView.image = downsample(imageAt:imgURL , to: CGSize(width: 200, height: 200), scale: UIScreen.main.scale)

    加载之前时是13M,加载之后是 17M,效果是很明显的,节省了大约 5M的内存空间。

    在对图片进行压缩时,我们应首选向下采样技术。

    SD源码分析解码过程

    在SDWebIamge中,一共有3种类型的解码器:SDImageiocoder, SDImageGIFCoder, SDImageAPNGCoder,根据DataBuffer的编码类型,使用相对应的编码器。

    在 -(UIImage *)decodedImageWithData:(NSData *)data方法中,配置解码参数,开始进行解码操作。

    在 + (UIImage *)createFrameAtIndex:(NSUInteger)index source:(CGImageSourceRef)source scale:(CGFloat)scale preserveAspectRatio:(BOOL)preserveAspectRatio thumbnailSize:(CGSize)thumbnailSize options:(NSDictionary )options 中,完成图像解码

    怎么在iOS中高效的加载图片

    选择正确的图片渲染格式

    渲染格式

    在 iOS中,渲染图片格式有4种

    • Alpha 8 Format:1字节显示1像素,擅长显示单色调的图片。

    • Luminance and alpha 8 format: 亮度和 alpha 8 格式,2字节显示1像素,擅长显示有透明度的单色调图片。

    • SRGB Format: 4个字节显示1像素。

    • Wide Format: 广色域格式,8个字节显示1像素。适用于高精度图片,

    如何正确的选择渲染格式

    正确的思路是:不选择渲染格式,让渲染格式选择你。

    使用 UIGraphicsImageRender来替换UIGraphicsBeginImageContextWithOptions,前者在iOS12以后,会自动选择渲染格式,后者默认都会选择SRGB Format。

    func render() -> UIImage{   let bounds = CGRect(x: 0, y: 0, width: 300, height: 100)   let render = UIGraphicsImageRenderer(size: bounds.size)   let image = render.image { context in       UIColor.blue.setFill()           let path = UIBezierPath(roundedRect: bounds, byRoundingCorners: UIRectCorner.allCorners, cornerRadii: CGSize(width: 20, height: 20))       path.addClip()       UIRectFill(bounds)    }    return image}

    此时,系统为自动选择Alpha 8 Format格式,内容空间占用,将会减少75%。

    减少后备存储器的使用

    减少或者不使用 draw(rect:) 方法

    在需要绘制带有子视图的View时,不使用 draw(rect:)方法,使用系统的View属性或者添加子视图的方式,将绘制工作交给系统来处理。

    背景色直接通过UIView.backgroundColor设置,而非使用draw(rect:)

    如何在列表中加载图片

    我们在开发中,一般会对图片进行子线程异步加载,在后台进行 解码和下采样。在列表中,有时会加载很多图片,此时应该注意线程爆炸问题。

    线程爆炸

    当我们要求系统去做比CPU能够做的工作更多的工作时就会发生这种情况,比如我们要显示8张图片,但我们只有两个CPU,就不能一次完成所有这些工作,无法在不存在的CPU上进行并行处理,为了避免向一个全局队列中异步的分配任务时发生死,GCD将创建新线程来捕捉我们要求它所做的工作,然后CPU将花费大量时间,在这些线程之间进行切换,尝试在所有工作上取得我们要求操作系统为我们做的渐进式进展,在这些线程之间不停切换,实际上是相当大的开销,现在不是简单地将工作分派到全局异步队列之一,而是创建一个串行队列,在预取的方法中,异步的将工作分派到该队列,它的确意味着单个图像的加载,可能要比以前晚才能开始取得进展,但CPU将花费更少的时间,在它可以做的小任务之间来回切换。

    在SDWebImage中,解码的队列  _coderQueue.maxConcurrentOperationCount = 1就是一个串行队列。这样就很好的解决了多图片异步解码时,线程爆炸问题。

    以上是“怎么在iOS中高效的加载图片”这篇文章的所有内容,感谢各位的阅读!希望分享的内容对大家有帮助,更多相关知识,欢迎关注编程网精选频道!

    --结束END--

    本文标题: 怎么在iOS中高效的加载图片

    本文链接: https://lsjlt.com/news/304134.html(转载时请注明来源链接)

    有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

    猜你喜欢
    • 怎么在iOS中高效的加载图片
      这篇文章主要介绍怎么在iOS中高效的加载图片,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!图片的渲染流程在iOS中使用 UIImage和UIImageView来记载图片,他俩遵守经典的MVC架构,UIImage相当于...
      99+
      2023-06-25
    • 如何在iOS中高效的加载图片详解
      目录前言图片的渲染流程DataBufferSD源码分析ImageBuffer占用内存大小Xcode测试如何减少图像占用内存向下采样SD源码分析解码过程选择正确的图片渲染格式渲染格式如...
      99+
      2022-05-25
      ios 加载 图片
    • 怎么在html中加载图片
      这篇文章将为大家详细讲解有关怎么在html中加载图片,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。第一种:img标签插入图片<img src="h6course.p...
      99+
      2023-06-15
    • 怎么在webView中加载html图片
      这篇文章给大家介绍怎么在webView中加载html图片,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。当解析接口 突然出现一个xml形式的html格式的字符串的时候不用慌张,正常去交给webview的loaddata方...
      99+
      2023-06-09
    • css怎么使用高斯模糊的效果逐步加载图片
      本篇内容主要讲解“css怎么使用高斯模糊的效果逐步加载图片”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“css怎么使用高斯模糊的效果逐步加载图片”吧!用过 Me...
      99+
      2024-04-02
    • css怎么加载图片
      本文小编为大家详细介绍“css怎么加载图片”,内容详细,步骤清晰,细节处理妥当,希望这篇“css怎么加载图片”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。 ...
      99+
      2024-04-02
    • Web中怎么加载图片资源
      Web中怎么加载图片资源,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。浏览器的工作流程要研究图片资源的加载和渲染,我们先要了解...
      99+
      2024-04-02
    • 详解Android 教你打造高效的图片加载框架
      1、概述 优秀的图片加载框架不要太多,什么UIL , Volley ,Picasso,Imageloader等等。但是作为一名合格的程序猿,必须懂其中的实现原理,于是乎,今天...
      99+
      2022-06-06
      图片 框架 Android
    • 利用CSS、JavaScript及Ajax实现高效的图片预加载
      方法一:用CSS和JavaScript实现预加载 实现预加载图片有很多方法,包括使用CSS、JavaScript及两者的各种组合。这些技术可根据不同设计场景设计出相应的解决方案,十分...
      99+
      2022-11-15
      CSS JavaScript Ajax 图片预加载
    • jQuery中图片懒加载lazyload.js怎么用
      这篇文章将为大家详细讲解有关jQuery中图片懒加载lazyload.js怎么用,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。lazyload是一个用Javascript...
      99+
      2024-04-02
    • webpack中css加载和图片加载功能怎么使用
      这篇文章主要介绍“webpack中css加载和图片加载功能怎么使用”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“webpack中css加载和图片加载功能怎么使用”文章能帮助大家解决问题。css加载器...
      99+
      2023-07-05
    • 怎么在Android中加载长图
      本篇文章为大家展示了怎么在Android中加载长图,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。Android是什么Android是一种基于Linux内核的自由及开放源代码的操作系统,主要使用于移动...
      99+
      2023-06-14
    • 怎么在HTML5中实现一个图片预加载功能
      这篇文章给大家介绍怎么在HTML5中实现一个图片预加载功能,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。在HTML5中,我们可以使用drawImage方法在canvas上进行画图操作,其基本代码如下:var ...
      99+
      2023-06-09
    • Glide图片加载框架怎么在Android应用中使用
      这篇文章将为大家详细讲解有关Glide图片加载框架怎么在Android应用中使用,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。简介Glide是一款图片加载框架,可以在Android平台上以简...
      99+
      2023-05-31
      android glide roi
    • html中怎样加载本地图片
      这篇文章给大家分享的是有关html中怎样加载本地图片的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。html有什么特点1、简易性:超级文本标记语言版本升级采用超集方式,从而更加灵活方便,适合初学前端开发者使用。2、...
      99+
      2023-06-08
    • vue中图片加载不出来怎么办
      这篇文章主要为大家展示了“vue中图片加载不出来怎么办”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“vue中图片加载不出来怎么办”这篇文章吧。一、项目打包完成后,打开整体空白1、路径问题原因在v...
      99+
      2023-06-29
    • js怎么实现图片的懒加载
      这篇文章给大家分享的是有关js怎么实现图片的懒加载的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。图片的懒加载是前端优化必须要掌握的东西,图片实现懒加载可以节省带宽又可以减轻我们网页的负荷。接下来我来记录一下我所掌...
      99+
      2023-06-14
    • iOS开发中用imageIO渐进加载图片及获取exif的方法
      imageIO完成渐进加载图片 一、常见渐进加载图片模式     目前我们看到的渐进加载主要有以下三种实现方式:     1)  依次从web上加载不同...
      99+
      2022-05-16
      iOS 图片
    • HTML5怎么实现图片无限加载的瀑布流效果
      本篇内容主要讲解“HTML5怎么实现图片无限加载的瀑布流效果”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“HTML5怎么实现图片无限加载的瀑布流效果”吧!代码如...
      99+
      2024-04-02
    • css怎么在背景图片上加图片
      在 css 中可以叠加图片到背景图片上,方法包括:指定图片 url(1)、调整位置(2)、设置大小(3)、控制透明度(4)、使用 css 滤镜(5)。 如何在 CSS 中在背景图片上叠...
      99+
      2024-04-25
      css
    软考高级职称资格查询
    编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
    • 官方手机版

    • 微信公众号

    • 商务合作