iOS开发中使用Quartz2D绘图及自定义UIImageView控件
绘制基本图形
一、简单说明
图形上下文(graphics context):是一个cgcontextref类型的数据
图形上下文的作用:保存绘图信息、绘图状态
决定绘制的输出目标(绘制到什么地方去?)(输出目标可以是pdf文件、bitmap或者显示器的窗口上)
相同的一套绘图序列,指定不同的graphics context,就可将相同的图像绘制到不同的目标上。
quartz2d提供了以下几种类型的graphics context:
bitmap graphics context
pdf graphics context
window graphics context
layer graphics context
printer graphics context
只要上下文不同,绘制的地方就不同。
本文说明如何把图片绘制到bitmap上面去,即要求生成一张图片,图片上面保存了绘图信息。
bitmap就是图片,相当于系统的uiimage。一个uiimage就是一个bitmap
二、怎么把图片绘制到bitmap上?
注意:不能在drawrect:方法中直接获取bitmap的上下文,需要我们自己进行创建。
代码示例:
//
// yyviewcontroller.m
// 06-绘制基本图形
//
// created by apple on 14-6-22.
// copyright (c) 2014年 itcase. all rights reserved.
//
#import "yyviewcontroller.h"
@interface yyviewcontroller ()
@property (weak, nonatomic) iboutlet uiimageview *iv;
@end
@implementation yyviewcontroller
- (void)viewdidload
{
[super viewdidload];
//加载图片
//0.创建一个bitmap上下文
//c语言的方法
// cgbitmapcontextcreate(<#void *data#>, <#size_t width#>, <#size_t height#>, <#size_t bitspercomponent#>, <#size_t bytesperrow#>, <#cgcolorspaceref space#>, <#cgbitmapinfo bitmapinfo#>)
//oc中封装的方法
//方法1
// uigraphicsbeginimagecontext(<#cgsize size#>);
//方法2
uigraphicsbeginimagecontextwithoptions( cgsizemake(200, 200), no, 0);
//1.获取bitmap上下文
cgcontextref ctx = uigraphicsgetcurrentcontext();
//2.绘图(画一个圆)
cgcontextaddellipseinrect(ctx, cgrectmake(0, 0, 100, 100));
//3.渲染
cgcontextstrokepath(ctx);
//4.获取生成的图片
uiimage *image=uigraphicsgetimagefromcurrentimagecontext();
//5.显示生成的图片到imageview
self.iv.image=image;
//6.保存绘制好的图片到文件中
//先将图片转换为二进制数据,然后再将图片写到文件中
// uiimagejpegrepresentation(image, 1); //第二个参数为保存的图片的效果
nsdata *data=uiimagepngrepresentation(image);
[data writetofile:@"/users/apple/desktop/abc.png" atomically:yes];
}
- (void)didreceivememorywarning
{
[super didreceivememorywarning];
// dispose of any resources that can be recreated.
}
@end
程序执行效果:
程序执行完毕后,会在指定的位置创建一个abc.png的图片
补充说明:
1.创建bitmap图形上下文的方法
//方法1 uigraphicsbeginimagecontext(<#cgsize size#>);
//方法2 uigraphicsbeginimagecontextwithoptions(cgsize size, bool opaque, cgfloat scale)
使用两个方法同样都可以创建,但是使用第一个方法将来创建的图片清晰度和质量没有第二种方法的好。
方法2接收三个参数:
cgsize size:指定将来创建出来的bitmap的大小
bool opaque:设置透明yes代表透明,no代表不透明
cgfloat scale:代表缩放,0代表不缩放
创建出来的bitmap就对应一个uiimage对象
2.quartz2d的内存管理
使用含有“create”或“copy”的函数创建的对象,使用完后必须释放,否则将导致内存泄露
使用不含有“create”或“copy”的函数获取的对象,则不需要释放
如果retain了一个对象,不再使用时,需要将其release掉
可以使用quartz 2d的函数来指定retain和release一个对象。例如,如果创建了一个cgcolorspace对象,则使用函数cgcolorspaceretain和cgcolorspacerelease来retain和release对象。
也可以使用core foundation的cfretain和cfrelease。注意不能传递null值给这些函数
自定义uiimageview控件
一、实现思路
quartz2d最大的用途在于自定义view(自定义ui控件),当系统的view不能满足我们使用需求的时候,自定义view。
使用quartz2d自定义view,可以从模仿系统的imageview的使用开始。
需求驱动开发:模仿系统的imageview的使用过程
1.创建
2.设置图片
3.设置frame
4.把创建的自定义的view添加到界面上(在自定义的view中,需要一个image属性接收image图片参数->5)。
5.添加一个image属性(接下来,拿到image之后,应该把拿到的这个image给渲染出来。怎么渲染?自定义的view怎么把图片显示出来?->把图片给画出来,所以需要重写自定义view的drawrect:方法)。
6.重写自定义view的drawrect:方法,在该方法内部画出图形。
二、代码实现
系统自带的imageview的使用
//
// yyviewcontroller.m
// 02-自定义uiimageview
//
// created by apple on 14-6-22.
// copyright (c) 2014年 itcase. all rights reserved.
//
#import "yyviewcontroller.h"
@interface yyviewcontroller ()
@end
@implementation yyviewcontroller
- (void)viewdidload
{
[super viewdidload];
//系统的uiimageview的使用
// 1.创建一个uiimageview
uiimageview *iv=[[uiimageview alloc]init];
// 2.设置图片
iv.image=[uiimage imagenamed:@"me"];
// 3.设置frame
iv.frame=cgrectmake(100, 100, 100, 100);
// 4.把创建的自定义的view添加到界面上
[self.view addsubview:iv];
}
@end
实现效果:
使用quartz2d自定义view,代码如下:
新建一个自定义的类,让其继承自uiview,yyimageview.h文件代码如下:
//
// yyimageview.m
// 02-自定义uiimageview
//
// created by apple on 14-6-22.
// copyright (c) 2014年 itcase. all rights reserved.
//
#import "yyimageview.h"
@implementation yyimageview
//重写drawrect:方法
- (void)drawrect:(cgrect)rect
{
[self.image drawinrect:rect];
}
@end
在主控制器中,模仿系统自带的uiimageview的使用过程,实现同样的效果。
//
// yyviewcontroller.m
// 02-自定义uiimageview
//
// created by apple on 14-6-22.
// copyright (c) 2014年 itcase. all rights reserved.
//
#import "yyviewcontroller.h"
#import "yyimageview.h"
@interface yyviewcontroller ()
@end
@implementation yyviewcontroller
- (void)viewdidload
{
[super viewdidload];
// //系统的uiimageview的使用
//// 1.创建一个uiimageview
// uiimageview *iv=[[uiimageview alloc]init];
//// 2.设置图片
// iv.image=[uiimage imagenamed:@"me"];
//// 3.设置frame
// iv.frame=cgrectmake(100, 100, 100, 100);
//// 4.把创建的自定义的view添加到界面上
// [self.view addsubview:iv];
//自定义uiimageview
//1.创建
//2.设置图片
//3.设置frame
//4.把创建的自定义的view添加到界面上
yyimageview *yyiv=[[yyimageview alloc]init];
yyiv.image=[uiimage imagenamed:@"me"];
yyiv.frame=cgrectmake(100, 100, 100, 100);
[self.view addsubview:yyiv];
}
@end
三、完善
存在的问题?
在界面上,添加一个按钮,要求点击按钮,能够实现图片的切换。
//
// yyviewcontroller.m
// 02-自定义uiimageview
//
// created by apple on 14-6-22.
// copyright (c) 2014年 itcase. all rights reserved.
//
#import "yyviewcontroller.h"
#import "yyimageview.h"
@interface yyviewcontroller ()
@property(nonatomic,strong)uiimageview *imageview;
@end
@implementation yyviewcontroller
- (void)viewdidload
{
[super viewdidload];
//系统的uiimageview的使用
// 1.创建一个uiimageview
uiimageview *iv=[[uiimageview alloc]init];
// 2.设置图片
iv.image=[uiimage imagenamed:@"me"];
// 3.设置frame
iv.frame=cgrectmake(100, 100, 100, 100);
// 4.把创建的自定义的view添加到界面上
[self.view addsubview:iv];
self.imageview=iv;
//自定义uiimageview
//1.创建
//2.设置图片
//3.设置frame
//4.把创建的自定义的view添加到界面上
// yyimageview *yyiv=[[yyimageview alloc]init];
// yyiv.image=[uiimage imagenamed:@"me"];
// yyiv.frame=cgrectmake(100, 100, 100, 100);
// [self.view addsubview:yyiv];
//添加一个button按钮,当点击button按钮的时候,切换图片
uibutton *btn=[[uibutton alloc]initwithframe:cgrectmake(100, 300, 100, 50)];
[btn settitlecolor:[uicolor blackcolor] forstate:uicontrolstatenormal];
[btn settitle:@"点击切换" forstate:uicontrolstatenormal];
[btn addtarget:self action:@selector(btnclick) forcontrolevents:uicontroleventtouchupinside];
[self.view addsubview:btn];
}
-(void)btnclick
{
uiimage *image=[uiimage imagenamed:@"psb.jpeg"];
self.imageview.image=image;
}
@end
点击按钮后,实现图片的切换。
说明:系统的uiimage可以替换。而自定义imageview不会变换,因为自定义的view要想换图片,需要重新绘制并渲染一次图片。所以在拿到替换图片的时候,需要重新绘制一次图片,重写setimage方法。
完善后的代码如下:
主控制器中,yyviewcontroller.m文件的代码:
//
// yyviewcontroller.m
// 02-自定义uiimageview
//
// created by apple on 14-6-22.
// copyright (c) 2014年 itcase. all rights reserved.
//
#import "yyviewcontroller.h"
#import "yyimageview.h"
@interface yyviewcontroller ()
@property(nonatomic,strong)uiimageview *imageview;
@property(nonatomic,strong)yyimageview *yyimageview;
@end
@implementation yyviewcontroller
- (void)viewdidload
{
[super viewdidload];
// //系统的uiimageview的使用
//// 1.创建一个uiimageview
// uiimageview *iv=[[uiimageview alloc]init];
//// 2.设置图片
// iv.image=[uiimage imagenamed:@"me"];
//// 3.设置frame
// iv.frame=cgrectmake(100, 100, 100, 100);
//// 4.把创建的自定义的view添加到界面上
// [self.view addsubview:iv];
// self.imageview=iv;
//自定义uiimageview
//1.创建
//2.设置图片
//3.设置frame
//4.把创建的自定义的view添加到界面上
yyimageview *yyiv=[[yyimageview alloc]init];
yyiv.image=[uiimage imagenamed:@"me"];
yyiv.frame=cgrectmake(100, 100, 100, 100);
[self.view addsubview:yyiv];
self.yyimageview=yyiv;
//添加一个button按钮,当点击button按钮的时候,切换图片
uibutton *btn=[[uibutton alloc]initwithframe:cgrectmake(100, 300, 100, 50)];
[btn settitlecolor:[uicolor blackcolor] forstate:uicontrolstatenormal];
[btn settitle:@"点击切换" forstate:uicontrolstatenormal];
[btn addtarget:self action:@selector(btnclick) forcontrolevents:uicontroleventtouchupinside];
[self.view addsubview:btn];
}
-(void)btnclick
{
nslog(@"按钮被点击了");
uiimage *image=[uiimage imagenamed:@"psb.jpeg"];
// self.imageview.image=image;
self.yyimageview.image=image;
}
@end
yyimageview.m文件的代码:
//
// yyimageview.m
// 02-自定义uiimageview
//
// created by apple on 14-6-22.
// copyright (c) 2014年 itcase. all rights reserved.
//
#import "yyimageview.h"
@implementation yyimageview
//重写drawrect:方法
- (void)drawrect:(cgrect)rect
{
[self.image drawinrect:rect];
}
//重写set方法
-(void)setimage:(uiimage *)image
{
_image=image;
[self setneedsdisplay];
}
@end