免费开源的iOS开发学习平台

UIImage与绘图:1-绘制图片

UIImageView是一个可以显示图片的视图控件,其能够显示图片的本质也是通过绘图来实现的,即,首先加载一张图片(UIImage对象),然后在drawRect:方法中把图片绘制到绘图上下文中,并显示出来。

创建UIImage对象

UIImage类中提供了创建UIImage对象的方法,这其中既有类方法(class method),也有实例方法(instance method),最常用的有如下几个方法:

  • imageNamed: 类方法,从main bundle中读取图片文件。通常情况下图片放置在工程的Assets.xcassets文件夹中,只要提供文件名即可创建UIImage对象;
+ (nullable UIImage *)imageNamed:(NSString *)name;
  • imageWithContentOfFile: 类方法,从工程文件中读取图片,传入一个图片路径参数,最终得到一个UIImage对象;
+ (nullable UIImage *)imageWithContentsOfFile:(NSString *)path;
  • imageWithData: 类方法,从一个NSData对象中加载图片;
+ (nullable UIImage *)imageWithData:(NSData *)data;
  • initWithContentsOfFile:实例方法,与imageWithContentOfFile类似,需要传入图片的路径。
- (nullable instancetype)initWithContentsOfFile:(NSString *)path;

下方的示例代码中演示了创建UIImage对象的常用方法。

    UIImage *image1 = [UIImage imageNamed:@"logo"];
    NSString *path = [[NSBundle mainBundle] pathForResource:@"99ios" ofType:@"png"];
    UIImage *image2 = [UIImage imageWithContentsOfFile:path];

绘图方法

在UIImage类中提供了2个主要的绘图方法,可以把图片绘制到绘图上下文中(有些类似于绘画结束后盖印章,只需一盖就可以把一个完整的印章图形显示在纸面上,这个和用笔画画有些区别):

  • drawAtPoint: 以图片的左上角为锚点,显示在制定的Point位置,图片不做压缩处理,显示原始大小;
- (void)drawAtPoint:(CGPoint)point;
  • drawInRect: 把图片装在一个矩形区域内显示,图片有可能会放大/缩小或者拉伸/压缩。
- (void)drawInRect:(CGRect)rect; 

示例代码

下方的示例代码中,分别使用了drawAtPoint:以及drawInRect:方法进行图片绘制,大家可以体会这两种方法的使用区别以及绘图顺序对最终效果的影响。

  • 创建一个名为MainView的类,继承自UIView

  • 在StoryBoard中,修改主控制器View的类型为MainView

  • 分别在Assets.xcassets以及工程中添加一张图片,名称为logo.png和99ios.png,像素大小推荐200*200

  • 在MainView.m文件中,添加如下代码

-(void)drawRect:(CGRect)rect{
    UIImage *image1 = [UIImage imageNamed:@"logo"];
    
    NSString *path = [[NSBundle mainBundle] pathForResource:@"99ios" ofType:@"png"];
    UIImage *image2 = [UIImage imageWithContentsOfFile:path];
    
    //先绘制image1
    [image1 drawInRect:CGRectMake(0, 250, 100, 100)];
    //再绘制image2
    [image2 drawAtPoint:CGPointZero];
}

运行结果:

注意:根据绘图原理可知,绘制图片的最后合成效果,与绘制的顺序有关系,即先绘制的图片在下方,后绘制的图片在上方,会覆盖之前绘制的图片。如果上面的代码中,改变绘制的顺序,会得到不同的显示结果。如下图所示:

-(void)drawRect:(CGRect)rect{
    UIImage *image1 = [UIImage imageNamed:@"logo"];
    
    NSString *path = [[NSBundle mainBundle] pathForResource:@"99ios" ofType:@"png"];
    UIImage *image2 = [UIImage imageWithContentsOfFile:path];
    
    //先绘制image2
    [image2 drawAtPoint:CGPointZero];
    //再绘制image1
    [image1 drawInRect:CGRectMake(0, 150, 100, 100)];
}

运行结果。

https://github.com/99ios/14.2.1