版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
【移动应用开发技术】怎么在iOS中使用CIFilter生成一个二维码
这篇文章给大家介绍怎么在iOS中使用CIFilter生成一个二维码,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。1二维码的生成生成一个二维码也就是根据提供的数据内容转换成一张二维码图像。从iOS7开始,我们只需要使用CIFilter中的CIQRCodeGenerator就可以轻易实现。只不过这样生成的二维码图像是一个CIImage对象,如果要在图像视图中显示,需要将其转换为UIImage对象。具体步骤如下:①、使用名为CIQRCodeGenerator的过滤器创建一个CIFilter对象。CIFilter
*filter
=
[CIFilter
filterWithName:@"CIQRCodeGenerator"]②、为CIFilter对象设置inputMessage和inputCorrectionLevel参数。inputMessage:是一个NSData对象,用于表示被编码的数据。对于字符串或者URL,需要使用NSISOLatin1StringEncoding字符串编码将其转换为NSData对象。要注意的是,NSISOLatin1StringEncoding编码对于中文或表情无法生成,需要的话可以使用NSUTF8StringEncoding替换。inputCorrectionLevel:是一个NSString对象,通常使用单个字母来指定纠错率,默认值是M。该参数控制输出图像中编码的附加数据量以提供纠错。其纠错率越高,输出的图像越大,同时也允许代码的更大区域被破坏或模糊。通常有L、M、Q、H这四种可能的纠正模式,分别代表了7%、15%、25%、30%的错误恢复能力。③、使用CIFilter对象的outputImage属性获取生成的二维码图像CIImage
*outputImage
=
filter.outputImage;④、对生成的二维码图像进行缩放。由于生成的二维码图像尺寸一般都比较小,为了避免模糊,通常需要对它进行缩放以适应图像视图的大小。其缩放比例一般为图像视图宽度(或高度)与二维码图像宽度(或高度)的比值。CGFloat
scaleX
=
imageView.bounds.size.width
/
qrcodeImage.extent.size.width;
CGFloat
scaleY
=
imageView.bounds.size.height
/
qrcodeImage.extent.size.height;
CIImage
*transformedImage
=
[qrcodeImage
imageByApplyingTransform:CGAffineTransformMakeScale(scaleX,
scaleY)];⑤、将二维码图像转换为UIImage对象。imageView.image
=
[UIImage
imageWithCIImage:transformedImage];2应用示例下面,我们就做一个如下图所示的二维码生成器:其中主要实现的功能有:生成和删除二维码。通过滑动条对二维码图像进行缩放。将二维码保存到相册。2.1创建项目打开Xcode,创建一个新的项目(File\New\Project...),选择iOS一栏下的Application中的SingleViewApplication模版,然后点击Next,填写项目选项。在ProductName中填写QRCodeGeneratorDemo,选择Objective-C语言,点击Next,选择文件位置,并单击Create创建项目。
2.2构建界面打开Main.storyboard文件,在当前控制器中嵌入导航控制器,并添加标题QRCodeGenerator:在视图控制器中添加文本框、按钮、图像视图等,布局如下:其中各元素及作用:TextField:用于输入想要转换为二维码的数据内容,包括文本或URL字符串。Button:在这里具有双重作用,用于生成和清除二维码。ImageView:用于显示生成的二维码图像。Slider:用来缩放生成的二维码图像。打开辅助编辑器,将storyboard中的元素连接到代码中:
2.3添加代码2.3.1生成二维码图像由于使用CIFilter对象生成的二维码图像将是一个CIImage对象,所以需要先在ViewController.m文件的接口部分声明一个CIImage对象的属性:@property
(strong,
nonatomic)
CIImage
*qrcodeImage;然后在实现部分添加generateQRCodeImage方法及代码:-
(void)generateQRCodeImage
{
NSData
*data
=
[self.textField.text
dataUsingEncoding:NSISOLatin1StringEncoding
allowLossyConversion:NO];
//
创建并设置CIFilter对象
CIFilter
*filter
=
[CIFilter
filterWithName:@"CIQRCodeGenerator"];
[filter
setValue:data
forKey:@"inputMessage"];
[filter
setValue:@"Q"
forKey:@"inputCorrectionLevel"];
//
获取生成的CIImage对象
self.qrcodeImage
=
filter.outputImage;
//
转换成UIImage对象,并显示在图像视图中
self.imageView.image
=
[UIImage
imageWithCIImage:self.qrcodeImage];
}在clickButton:方法中调用该方法:-
(IBAction)clickButton:(id)sender
{
[self
generateQRCodeImage];
}此时,运行程序,在文本框中输入内容,点击按钮就可以看到生成的二维码:仔细的话你会发现这里的二维码比较模糊,这是由于生成的二维码尺寸较小,在imageView中显示时被拉伸导致的。下面我们就通过调整二维码的缩放来解决图像模糊的问题。修改generateQRCodeImage方法中的代码如下:-
(void)generateQRCodeImage
{
...
//
获取生成的CIImage对象
self.qrcodeImage
=
filter.outputImage;
//
缩放CIImage对象
CGFloat
scaleX
=
self.imageView.bounds.size.width
/
self.qrcodeImage.extent.size.width;
CGFloat
scaleY
=
self.imageView.bounds.size.height
/
self.qrcodeImage.extent.size.height;
CIImage
*transformedImage
=
[self.qrcodeImage
imageByApplyingTransform:CGAffineTransformMakeScale(scaleX,
scaleY)];
//
将调整后的CIImage对象转换成UIImage对象,并显示在图像视图中
self.imageView.image
=
[UIImage
imageWithCIImage:transformedImage];
}再次运行,你会看到一张清晰的二维码:
2.3.2删除二维码图像在这个demo中,按钮具有双重作用:即生成二维码和删除二维码。因此需要在clickButton:方法中先判断二维码图像是否存在:如果不存在,点击按钮生成一张二维码图像,按钮的标题变为"Clear"。如果存在,点击按钮删除二维码图像,按钮的标题变为"Generate"。修改clickButton:方法中的代码如下:-
(IBAction)clickButton:(id)sender
{
if
(self.qrcodeImage
==
nil)
{
[self
generateQRCodeImage];
[self.button
setTitle:@"Clear"
forState:UIControlStateNormal];
}
else
{
[self
clearQRCodeImage];
[self.button
setTitle:@"Generate"
forState:UIControlStateNormal];
}
}下面我们就添加clearQRCodeImage方法并实现它:-
(void)clearQRCodeImage
{
self.imageView.image
=
nil;
self.qrcodeImage
=
nil;
self.textField.text
=
nil;
}至此,二维码的生成和删除已基本完成,但为了有良好的体验,我们还需要考虑下面的情况:在文本框未输入的情况下点击按钮是否生成二维码。切换按钮时文本框的响应状态以及键盘出现与消失。滑动条的显示和隐藏。于是,在clickButton:方法中添加下面的代码:-
(IBAction)clickButton:(id)sender
{
if
(self.qrcodeImage
==
nil)
{
if
([self.textField.text
isEqualToString:@""])
{
return;
}
[self
generateQRCodeImage];
[self.textField
resignFirstResponder];
[self.button
setTitle:@"Clear"
forState:UIControlStateNormal];
}
else
{
[self
clearQRCodeImage];
[self.button
setTitle:@"Generate"
forState:UIControlStateNormal];
}
self.textField.enabled
=
!self.textField.enabled;
self.slider.hidden
=
!self.slider.hidden;
}最后,考虑到程序启动时滑动条不应该显示(滑动条只在生成二维码时出现),还需要在viewDidLoad方法中设置其hidden属性:-
(void)viewDidLoad
{
[super
viewDidLoad];
self.slider.hidden
=
YES;
}可以再次运行试下。2.3.3缩放二维码图像缩放显示的二维码主要是通过拖动滑动条缩放imageView来完成的。在实现部分找到changeScale:方法,并添加代码下面的代码即可:-
(IBAction)changeScale:(id)sender
{
self.imageView.transform
=
CGAffineTransformMakeScale((CGFloat)self.slider.value,
(CGFloat)self.slider.value);
}需要注意的是,self.slider.value是float类型,而CGAffineTransformMakeScale方法的参数是CGFloat类型,因此在上面的代码中进行了类型转换。2.3.4保存二维码图像将生成的二维码图片保存到相机胶卷相册主要是使用UIImageWriteToSavedPhotosAlbum函数来实现的。其完整声明如下:复制代码代码如下:voidUIImageWriteToSavedPhotosAlbum(UIImage*image,idcompletionTarget,SELcompletionSelector,void*contextInfo);其中各参数及含义:image:表示要保存到相册的图像。completionTarget:可选的参数,表示图片保存后,调用完成选择器(completionSelector)的对象。completionSelector:可选的方法,表示图片保存后,completionTarget对象要调用的方法(即回调方法)。该方法应符合以下签名:-
(void)image:(UIImage
*)image
didFinishSavingWithError:(NSError
*)error
contextInfo:(void
*)contextInfo;contextInfo:可选的参数,用于提供一个上下文信息以通过参数传递给completionSelector。在这里我们的大致思路是:首先在imageView中添加单击手势,当用户点击二维码图像时会弹出一个提示框询问是否保存,如果用户点击保存按钮,那么就将二维码保存到相册中。下面是具体实现:打开Main.storyboard文件,从对象库中找到点击手势(TapGestureRecognizer),将其添加到视图控制器的ImageView上,完成之后会在控制器的顶部看到它:打开辅助编辑器,将其连接到代码中:为了使imageView能响应手势操作,需要在viewDidLoad中设置imageView的userInteractionEnabled属性:-
(void)viewDidLoad
{
...
self.imageView.userInteractionEnabled
=
YES;
}然后在实现部分找到tap:方法,并添加下面的代码:-
(IBAction)tap:(id)sender
{
//
添加提示框
UIAlertController
*alertController
=
[UIAlertController
alertControllerWithTitle:@"Save
QRCode?"
message:@"The
QRCode
will
be
saved
in
Camera
Roll
album."
preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction
*saveAction
=
[UIAlertAction
actionWithTitle:@"Save"
style:UIAlertActionStyleDefault
handler:^(UIAlertAction
*
_Nonnull
action)
{
//
保存二维码图像
[self
saveQRCodeImage];
}];
UIAlertAction
*cancelAction
=
[UIAlertAction
actionWithTitle:@"Cancel"
style:UIAlertActionStyleCancel
handler:nil];
[alertController
addAction:saveAction];
[alertController
addAction:cancelAction];
[self
presentViewController:alertController
animated:YES
completion:nil];
}这时编译器会有红色警告提示saveQRCodeImage方法未声明。接下来我们就在实现部分添加该方法来实现二维码的保存:-
(void)saveQRCodeImage
{
//
绘制图像
UIGraphicsBeginImageContext(self.imageView.image.size);
[self.imageView.image
drawInRect:self.imageView.bounds];
self.imageView.image
=
UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
//
保存图像
UIImageWriteToSavedPhotosAlbum(self.imageView.image,
nil,
nil,
nil);
}值得说明的是,这里的self.imageView.image是从CIImage对象转换来的,是保存不到相册的,需要先在图形上下文中绘制一下,生成一个新的图像,然后才能保存。此时,运行程序,点击生成的二维码图像你会看到下面的效果:但是点击Save按钮时,程序会崩溃,在控制台会看到下面的消息:Thisapphascrashedbecauseitattemptedtoaccessprivacy-sensitivedatawithoutausagedescription.Theapp'sInfo.plistmustcontainanNSPhotoLibraryAddUsageDescriptionkeywithastringvalueexplainingtotheuserhowtheappusesthisdata.这是因为iOS要求应用程序开发者在允许访问相册之前要先获得用户的许可。为此,我们必须在Info.plist文件中添加名为NSPhotoLibraryAddUsageDescription的键,并为其添加相应的描述:问题修复完成!再次运行,点击保存按钮,打开相册应用,你会看到刚才保存的二维码:到目前为止,我们的工作已基本完成,但是为了更完美一些,最好是在点击保存按钮之后能够收到是否保存成功的反馈。所以需要在saveQRCodeImage方法中更改UIImageWriteToSavedPhotosAlbum函数的参数:-
(void)saveQRCodeImage
{
...
//
保存图像
UIImageWriteToSavedPhotosAlbum(self.imageView.image,
self,
@selector(image:didFinishSavingWithError:contextInfo:),
nil);
}然后添加image:didFinishSaving
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 5A级景区旅游档案管理存在的问题及对策
- 3D打印技术在心血管疾病中的应用进展
- 304L不锈钢法兰配35CrMo紧固件腐蚀分析
- 21世纪初中国农村居民国内旅游流要素-结构耦合关系及时空演化分析
- 2018欧洲女子数学奥林匹克第1题探究
- 18.5 MW样机定子线圈结构及嵌线制造工艺分析
- 110 kV复合外套金属氧化锌避雷器爆炸故障分析
- 1000MW级机组接入220kV电网技术条件研究
- 高血压患者如何保持自我价值感
- 医疗机构内部传染病的防控策略
- 蛋白磷酸化与蛋白激酶
- 海洋的前世今生智慧树知到期末考试答案2024年
- 中小学教师高级职称专业水平能力测试复习资料大全
- 迎接青春挑战
- 基于SSM在线教育平台系统的设计与实现
- 朗致集团逻辑测评试卷2024
- 2024年安徽省合肥市蜀山区中考一模道德与法治试题
- 康复科护理服务
- 安管题库2024(矿安益考试平台题库)
- 经典收益权转让合同
- 《粮油食品加工技术》课程标准
评论
0/150
提交评论