美文网首页
iOS 圆角优化及栅格化下网络图片模糊问题与像素格式

iOS 圆角优化及栅格化下网络图片模糊问题与像素格式

作者: Singularity_Lee | 来源:发表于2019-07-11 20:34 被阅读0次

在页面多圆角视图的情况下,会导致页面卡顿,取消圆角绘制后会明显察觉页面流畅;
若在在tableview下,滚动视图每次都会执行绘制圆角,自然会造成页面UI阻塞。因而需要对圆角优化,提高页面流畅度。

self.layer.cornerRadius = cornerRadius;
self.layer.masksToBounds = YES;

// 设置栅格化后,图层会被渲染成图片,并且缓存,再次使用时,不会重新渲染
self.layer.rasterizationScale = [UIScreen mainScreen].scale;
self.layer.shouldRasterize = YES;
/* When true, the layer is rendered as a bitmap in its local coordinate
 * space ("rasterized"), then the bitmap is composited into the
 * destination (with the minificationFilter and magnificationFilter
 * properties of the layer applied if the bitmap needs scaling).
 * Rasterization occurs after the layer's filters and shadow effects
 * are applied, but before the opacity modulation. As an implementation
 * detail the rendering engine may attempt to cache and reuse the
 * bitmap from one frame to the next. (Whether it does or not will have
 * no affect on the rendered output.)
 *
 * When false the layer is composited directly into the destination
 * whenever possible (however, certain features of the compositing
 * model may force rasterization, e.g. adding filters).
 *
 * Defaults to NO. Animatable. */

@property BOOL shouldRasterize;

/* The scale at which the layer will be rasterized (when the
 * shouldRasterize property has been set to YES) relative to the
 * coordinate space of the layer. Defaults to one. Animatable. */

@property CGFloat rasterizationScale;

当 shouldRasterize 设成 YES 时,layer 被渲染成一个 bitmap位图,并缓存起来,等下次使用时不会再重新去渲染了。实现圆角本身就是在做颜色混合(blending),如果每次页面出来时都blending,消耗太大,这时shouldRasterize = ,下次就只是简单的从渲染引擎的缓存里读取那张 bitmap位图,节约系统资源。

位图就是一个像素数组,数组中的每个像素就代表着图片中的一个点。我们在应用中经常用到的 JPEG 和 PNG 图片就是位图。


但需要注意一点,在对UIImageView使用栅格化圆角后并使用SDWebImage加载网络图片会造成图片模糊问题,此时还是尽量使用无栅格化的圆角绘制方式。

self.layer.cornerRadius = cornerRadius;
self.layer.masksToBounds = YES;

不管是 JPEG 还是 PNG 图片,都是一种压缩的位图图形格式,而SDWebImage则是对图片进行强制解压缩。

猜测原因在于SDWebImage使用 CGBitmapContextCreate强制解压缩后的位图布局信息与绘制圆角渲染成的位图布局信息冲突,系统在CGImageAlphaInfo上只识别到了绘制圆角使用到的kCGImageAlphaNoneSkipFirst而非SDWebImage设置的kCGImageAlphaNoneSkipLast属性,导致颜色分量使用的是5位而不是8位,因此造成图像质量降低,造成了模糊问题。

/* Create a bitmap context. The context draws into a bitmap which is `width'
   pixels wide and `height' pixels high. The number of components for each
   pixel is specified by `space', which may also specify a destination color
   profile.  Note that the only legal case when `space' can be NULL is when
   alpha is specified as kCGImageAlphaOnly.The number of bits for each component
   of a pixel is specified by `bitsPerComponent'. The number of bytes per pixel
   is equal to `(bitsPerComponent * number of components + 7)/8'. Each row of
   the bitmap consists of `bytesPerRow' bytes, which must be at least
   `width * bytes per pixel' bytes; in addition, `bytesPerRow' must be an
   integer multiple of the number of bytes per pixel. `data', if non-NULL,
   points to a block of memory at least `bytesPerRow * height' bytes.
   If `data' is NULL, the data for context is allocated automatically and freed
   when the context is deallocated. `bitmapInfo' specifies whether the bitmap
   should contain an alpha channel and how it's to be generated, along with
   whether the components are floating-point or integer. */

/*CGBitmapContextCreate这个函数用于创建一个位图上下文,用来绘制一张宽 width 像素,高 height 像素的位图。*/

/*
data :如果不为 NULL ,那么它应该指向一块大小至少为 bytesPerRow * height 字节的内存;如果 为 NULL ,那么系统就会为我们自动分配和释放所需的内存,所以一般指定 NULL 即可;
width 和 height :位图的宽度和高度,分别赋值为图片的像素宽度和像素高度即可;
bitsPerComponent :像素的每个颜色分量使用的 bit 数,在 RGB 颜色空间下指定 8 即可;
bytesPerRow :位图的每一行使用的字节数,大小至少为 width * bytes per pixel 字节。有意思的是,当我们指定 0 时,系统不仅会为我们自动计算,而且还会进行 cache line alignment 的优化
space :就是我们前面提到的颜色空间,一般使用 RGB 即可;
bitmapInfo :位图的布局信息。
*/
CG_EXTERN CGContextRef __nullable CGBitmapContextCreate(void * __nullable data,
    size_t width, size_t height, size_t bitsPerComponent, size_t bytesPerRow,
    CGColorSpaceRef cg_nullable space, uint32_t bitmapInfo)
    CG_AVAILABLE_STARTING(10.0, 2.0);
第三方库参数信息
//CGBitmapInfo
typedef CF_ENUM(uint32_t, CGImageAlphaInfo) {
    kCGImageAlphaNone,               /* For example, RGB. */
    kCGImageAlphaPremultipliedLast,  /* For example, premultiplied RGBA */
    kCGImageAlphaPremultipliedFirst, /* For example, premultiplied ARGB */
    kCGImageAlphaLast,               /* For example, non-premultiplied RGBA */
    kCGImageAlphaFirst,              /* For example, non-premultiplied ARGB */
    kCGImageAlphaNoneSkipLast,       /* For example, RBGX. */
    kCGImageAlphaNoneSkipFirst,      /* For example, XRGB. */
    kCGImageAlphaOnly                /* No color data, alpha data only */
};

*   alpha 的信息;
*   颜色分量是否为浮点数;
*   像素格式的字节顺序。
//CGImageAlphaInfo
typedef CF_OPTIONS(uint32_t, CGBitmapInfo) {
    kCGBitmapAlphaInfoMask = 0x1F,

    kCGBitmapFloatInfoMask = 0xF00,
    kCGBitmapFloatComponents = (1 << 8),

    kCGBitmapByteOrderMask     = kCGImageByteOrderMask,
    kCGBitmapByteOrderDefault  = (0 << 12),
    kCGBitmapByteOrder16Little = kCGImageByteOrder16Little,
    kCGBitmapByteOrder32Little = kCGImageByteOrder32Little,
    kCGBitmapByteOrder16Big    = kCGImageByteOrder16Big,
    kCGBitmapByteOrder32Big    = kCGImageByteOrder32Big
} CG_AVAILABLE_STARTING(__MAC_10_0, __IPHONE_2_0);

*   是否包含 alpha ;
*   如果包含 alpha ,那么 alpha 信息所处的位置,在像素的最低有效位,比如 RGBA ,还是最高有效位,比如 ARGB ;
*   如果包含 alpha ,那么每个颜色分量是否已经乘以 alpha 的值,这种做法可以加速图片的渲染时间,因为它避免了渲染时的额外乘法运算。比如,对于 RGB 颜色空间,用已经乘以 alpha 的数据来渲染图片,每个像素都可以避免 3 次乘法运算,红色乘以 alpha ,绿色乘以 alpha 和蓝色乘以 alpha 。

网络图片的加载及解压缩讲解


像素格式

像素格式是用来描述每个像素的组成格式,包含信息内容

  • Bits per component :一个像素中每个独立的颜色分量使用的 bit 数;
  • Bits per pixel :一个像素使用的总 bit 数;
  • Bytes per row :位图中的每一行使用的字节数。

对于位图来说,像素格式并不是随意组合的,目前只支持以下有限的17种组合格式


组合模式

对于 iOS 来说,只支持 8 种像素格式。其中颜色空间为 Null 的 1 种,Gray 的 2 种,RGB 的 5 种,CMYK 的 0 种。换句话说,iOS 并不支持 CMYK 的颜色空间。

在16 或 32 位像素格式的 CMYK 和 RGB 颜色空间下,一个像素的表示方式


16 或 32 位像素格式的 CMYK 和 RGB 颜色空间下,一个像素的表示方式

在 32 位像素格式下,每个颜色分量使用 8 位;而在 16 位像素格式下,每个颜色分量则使用 5 位。


色彩模式ARGB_8888、ARGB_4444、 RGB_565、 ALPHA_8的区别

Bitmap.Config ARGB_8888:由4个8位组成,即A=8,R=8,G=8,B=8,那么一个像素点占8+8+8+8=32位(4字节)

Bitmap.Config ARGB_4444:由4个4位组成,即A=4,R=4,G=4,B=4,那么一个像素点占4+4+4+4=16位 (2字节)

Bitmap.Config RGB_565:没有透明度,R=5,G=6,B=5,,那么一个像素点占5+6+5=16位(2字节)

Bitmap.Config ALPHA_8:每个像素占8位,只有透明度,没有颜色。

一般情况下我们使用的色彩模式为ARGB_8888,这种模式下一个像素所占的大小为4字节,一个像素的位数总和越高,图像也就越逼真。

假设有一张480x800的图片,在色彩模式为ARGB_8888的情况下,会占用 4808004/1024KB=1500KB 的内存;而在RGB_565的情况下,占用的内存为:4808002/1024KB=750KB。

相关文章

  • iOS 圆角优化及栅格化下网络图片模糊问题与像素格式

    在页面多圆角视图的情况下,会导致页面卡顿,取消圆角绘制后会明显察觉页面流畅;若在在tableview下,滚动视图每...

  • 2018-07-04

    后台绘制圆角图片 参考链接链接 iOS 离屏渲染优化(Offscreen Render)

  • webgl基本概念

    光栅化 是将向量图形格式表示的图像转换成位图以用于显示器或者打印机输出的过程; 栅格即像素,栅格化即将矢量图形转化...

  • 移动端系列(适配)

    像素比 点、points (抽象单位 ) 像素渲染 (栅格化) 物理像素 (调整大小) dpi、p...

  • iOS图片圆角优化

    转载请注明出处:http://www.olinone.com/ Hi,又到了更新博客的时间,很高兴再次与大家见面。...

  • iOS 图片格式需求

    注意:苹果账号图片格式统一为png格式,单位统一为像素 icon 一定要直角,不需要倒圆角 提供最大 1024 *...

  • ios关于UI

    1.ios在控件上添加虚线边框 内容很详细,涉及到虚线边框圆角问题及解决过程。 2.ios截图 ①截某个显示图片的...

  • iOS 圆角优化

    iOS 圆角优化 方法3: 覆盖一个圆形镂空图片。详细介绍第三种:在需要显示圆角的图层上覆盖一个镂空的图片,根据颜...

  • PS如何将文字做旧

    输入文字。 右键图层->栅格化文字。 滤镜->风格化->扩散。 滤镜->模糊->高斯模糊。

  • 图片资源优化

    图片资源优化后的好处: 方案 iOS 使用Assets来管理资源; 使用TinyPng来优化png格式图片大小;T...

网友评论

      本文标题:iOS 圆角优化及栅格化下网络图片模糊问题与像素格式

      本文链接:https://www.haomeiwen.com/subject/nofjkctx.html