IOS:谈谈UIImage的一些知识?

2023-05-22


有一段时间没写博客了,中间隔了一个五一假期,差不多20天。在此期间,我准备在小组中分享,所以我推迟了。今天,我要写一些关于UIImage的东西。


在IOS中,UIImage是一个较高层次的类别,用于载入和绘制图像,更低层次的类别是CGImage,以及IOS5.0后新增的CIImage。现在我们主要谈谈UIImage的三个特点: imageOrientation, size, scale,一些初始化方法: imageNamed,imageWithContentsOfFile,以及几种draw开头绘制Image的方法。



首先,UIImagesize,scale特性


首先想一个问题:“一个图像的大小到底有多大?”


image的第一反应可能是.size,恭喜你答错了,正确的答案是图像的实际尺寸(像素)等于image。.乘以image乘以size.scale。假如你做过界面贴图,你可能会经常准备至少两套图片,一套1倍图片,一套图片已经被@2x命名为2倍图片。这样,当我们的程序在retina屏幕上运行时,系统会自动加载@2x的照片,它的size会和加载一倍图的size一样,但scale是2,这可以通过一个简单的小测试来验证。但是,为什么我们不直接将其载入两倍的尺寸呢?原因很简单,因为我们逻辑坐标系(单位为point)在界面布局中,实际绘制是在设备坐标系(单位为pixel)中进行的,系统会自动帮助我们完成从point到pixel的转换。事实上,这一比例正好与UIScreen中的scale相对应,这样整个scale的线条就可以串通了。



对比几种初始化方法的UIImage。


1、imageNamed:方法


imageNamed:这是UIImage的一种方法,它比我们看到的要多一点。其载入过程如下:


a. 检查系统缓存中是否存在该名称的图像,如果出现这种情况,直接返回。


b. 假如在系统缓存中有这个名字的图像,那么就会先载入缓存,然后再回到这个目标。


通过观察上面的操作,我们发现系统会缓存我们使用imageNamed:当方法载入图像时,系统会自动帮助我们缓存。这种机制适用于频繁使用界面贴图的载入,但如果需要在短时间内频繁载入一些一次性图像,尽量不要使用这种方法。


2、imageWithContentsOfFile:和initWithContentsOfFile:方法


与前一种方法一样,这两种方法都可以完成从文件中加载图像的功能。但是,它不会通过系统缓存,而是直接加载到文件系统中并返回。


顺便说一下,当接到内存警告时,系统可能会释放UIImage内部存储图像的内存,并在下一次需要绘制时重新加载。


3、imageWithCGImage:scale:orientation:方法


在这方面,使用CGImageRef来建立UIImage,在创建时也可以指定方法倍率和旋转方向。当scale设置为1时,新创建的图像将与原始图像大小相同,而orientaion则可以指定绘制新图像的方向。



UIImage的imageOrientation特性


UIImage具有imageOrientation的属性,其主要功能是控制image的绘制方向,共有以下8个方向:










typedef NS_ENUM(NSInteger, UIImageOrientation) {
    UIImageOrientationUp,            // default orientation   
    UIImageOrientationDown,          // 180 deg rotation      
    UIImageOrientationLeft,          // 90 deg CCW     (在官方文档中,编程发现left和right图像标反,在此更正)
    UIImageOrientationRight,         // 90 deg CW



UIImageOrientationUpMirrored, // as above but image mirrored along other axis. horizontal flip


UIImageOrientationDownMirrored, // horizontal flip


UIImageOrientationLeftMirrored, // vertical flip


UIImageOrientationRightMirrored, // vertical flip






默认方向是UIImageorientationup,这八个方向对应的绘制方如上图所示。在日常使用中,我们经常会遇到在windows中导入iPhone相册中的照片,发现方向不对的问题在于与这一特性有关,因为在导出照片时,在写exif中的方向信息时,并没有考虑到这一角度。因为这一特性可以控制image的绘制方向,所以我们可以通过改变这一特性来完成UIImage的旋转和旋转吗?带着这个问题,我们继续往下看。



UIImage的几种draw方法?


UIImage的几种draw方法都是用来绘制图像的利器,为什么要这么说?由于它在绘制图像时会考虑当前图像的方向,即根据imageOrientation绘制不同的方向。由于图像是在当前的context中绘制的,它还会考虑当前contexttransform的变化。有利于这两点,我们可以玩转图像的旋转和旋转。


目前网上大部分图像旋转都是通过建立CGBitmapContext,然后根据图像方向设置contexttransform来完成的,这种方法需要对整个矩阵的变化过程非常清楚,一个基本参数不多,结果就会出现问题。


以下是一种简单方便的图像旋转方法,主要是通过imageWithCGImage来实现的。:scale:orientation:为了完成所需的功能,指定不同的orientation,首先举一个典型的例子:


,我们将向左旋转90°,所以转过之后应该会显示出来。


,将原图从orientationUP转换为orientationLeft。以此类推为不同方向的旋转,只需仔细观察R的显示,这样在实现整个旋转和旋转的过程中就可以完全不考虑Transform那些东西,是否很简单。


以下是图像旋转和旋转的完整代码:




UIImage Rotate_Flip.h     
   UIImage Rotate_Flip.m


上述顺时针90只完成了图像。°,逆时针90°,180°旋转,水平翻转,数值旋转等等。如何实现随意视角转动?实际上也很简单,留给大家思考吧。虽然我们可以通过orientation简单地完成图像旋转,但是如果我们有时间,我们建议尽可能多地阅读通过transform完成旋转的代码,这样你就可以完全找出旋转矩阵是怎么回事。当然,在使用系统时,建议使用我上面提供的这种方法,因为不涉及真正的旋转操作,速度会快很多。


通过以上小例子,我们不难发现,API越高,帮助我们做的事情就越多。API越低,提供的灵活性就越多,但同时也带来了很多需要我们处理的东西。在重新编程的过程中,尽量使用高级API,最好了解底层的实现机制。只有这样,我们的程序才能更有效率,我们才能知道在哪里发现问题。


本文仅代表作者观点,版权归原创者所有,如需转载请在文中注明来源及作者名字。

免责声明:本文系转载编辑文章,仅作分享之用。如分享内容、图片侵犯到您的版权或非授权发布,请及时与我们联系进行审核处理或删除,您可以发送材料至邮箱:service@tojoy.com