這篇文章給大家介紹怎么在iOS中使用CIFilter生成一個(gè)二維碼,內(nèi)容非常詳細(xì),感興趣的小伙伴們可以參考借鑒,希望對大家能有所幫助。
成都創(chuàng)新互聯(lián)2013年開創(chuàng)至今,是專業(yè)互聯(lián)網(wǎng)技術(shù)服務(wù)公司,擁有項(xiàng)目成都網(wǎng)站建設(shè)、成都網(wǎng)站制作網(wǎng)站策劃,項(xiàng)目實(shí)施與項(xiàng)目整合能力。我們以讓每一個(gè)夢想脫穎而出為使命,1280元海倫做網(wǎng)站,已為上家服務(wù),為海倫各地企業(yè)和個(gè)人服務(wù),聯(lián)系電話:189820811081 二維碼的生成
生成一個(gè)二維碼也就是根據(jù)提供的數(shù)據(jù)內(nèi)容轉(zhuǎn)換成一張二維碼圖像。從iOS 7開始,我們只需要使用CIFilter中的CIQRCodeGenerator就可以輕易實(shí)現(xiàn)。只不過這樣生成的二維碼圖像是一個(gè)CIImage對象,如果要在圖像視圖中顯示,需要將其轉(zhuǎn)換為UIImage對象。具體步驟如下:
①、使用名為CIQRCodeGenerator的過濾器創(chuàng)建一個(gè)CIFilter對象。
CIFilter *filter = [CIFilter filterWithName:@"CIQRCodeGenerator"]
②、為CIFilter對象設(shè)置inputMessage和inputCorrectionLevel參數(shù)。
inputMessage:是一個(gè)NSData對象,用于表示被編碼的數(shù)據(jù)。對于字符串或者URL,需要使用NSISOLatin1StringEncoding字符串編碼將其轉(zhuǎn)換為NSData對象。要注意的是,NSISOLatin1StringEncoding編碼對于中文或表情無法生成,需要的話可以使用NSUTF8StringEncoding 替換。
inputCorrectionLevel:是一個(gè)NSString對象,通常使用單個(gè)字母來指定糾錯(cuò)率,默認(rèn)值是M。該參數(shù)控制輸出圖像中編碼的附加數(shù)據(jù)量以提供糾錯(cuò)。其糾錯(cuò)率越高,輸出的圖像越大,同時(shí)也允許代碼的更大區(qū)域被破壞或模糊。通常有L、M、Q、H這四種可能的糾正模式,分別代表了7%、15%、25%、30%的錯(cuò)誤恢復(fù)能力。
③、使用CIFilter對象的outputImage
屬性獲取生成的二維碼圖像
CIImage *outputImage = filter.outputImage;
④、對生成的二維碼圖像進(jìn)行縮放。
由于生成的二維碼圖像尺寸一般都比較小,為了避免模糊,通常需要對它進(jìn)行縮放以適應(yīng)圖像視圖的大小。其縮放比例一般為圖像視圖寬度(或高度)與二維碼圖像寬度(或高度)的比值。
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)];
⑤、將二維碼圖像轉(zhuǎn)換為UIImage對象。
imageView.image = [UIImage imageWithCIImage:transformedImage];
2 應(yīng)用示例
下面,我們就做一個(gè)如下圖所示的二維碼生成器:
其中主要實(shí)現(xiàn)的功能有:
生成和刪除二維碼。
通過滑動(dòng)條對二維碼圖像進(jìn)行縮放。
將二維碼保存到相冊。
2.1 創(chuàng)建項(xiàng)目
打開Xcode,創(chuàng)建一個(gè)新的項(xiàng)目(File\New\Project...),選擇iOS一欄下的Application中的Single View Application模版,然后點(diǎn)擊Next,填寫項(xiàng)目選項(xiàng)。在Product Name中填寫QRCodeGeneratorDemo,選擇Objective-C語言,點(diǎn)擊Next,選擇文件位置,并單擊Create創(chuàng)建項(xiàng)目。
2.2 構(gòu)建界面
打開Main.storyboard文件,在當(dāng)前控制器中嵌入導(dǎo)航控制器,并添加標(biāo)題QR Code Generator:
在視圖控制器中添加文本框、按鈕、圖像視圖等,布局如下:
其中各元素及作用:
Text Field:用于輸入想要轉(zhuǎn)換為二維碼的數(shù)據(jù)內(nèi)容,包括文本或URL字符串。
Button:在這里具有雙重作用,用于生成和清除二維碼。
Image View:用于顯示生成的二維碼圖像。
Slider:用來縮放生成的二維碼圖像。
打開輔助編輯器,將storyboard中的元素連接到代碼中:
2.3 添加代碼
2.3.1 生成二維碼圖像
由于使用CIFilter對象生成的二維碼圖像將是一個(gè)CIImage對象,所以需要先在ViewController.m文件的接口部分聲明一個(gè)CIImage對象的屬性:
@property (strong, nonatomic) CIImage *qrcodeImage;
然后在實(shí)現(xiàn)部分添加generateQRCodeImage
方法及代碼:
- (void)generateQRCodeImage { NSData *data = [self.textField.text dataUsingEncoding:NSISOLatin1StringEncoding allowLossyConversion:NO]; // 創(chuàng)建并設(shè)置CIFilter對象 CIFilter *filter = [CIFilter filterWithName:@"CIQRCodeGenerator"]; [filter setValue:data forKey:@"inputMessage"]; [filter setValue:@"Q" forKey:@"inputCorrectionLevel"]; // 獲取生成的CIImage對象 self.qrcodeImage = filter.outputImage; // 轉(zhuǎn)換成UIImage對象,并顯示在圖像視圖中 self.imageView.image = [UIImage imageWithCIImage:self.qrcodeImage]; }
在clickButton:
方法中調(diào)用該方法:
- (IBAction)clickButton:(id)sender { [self generateQRCodeImage]; }
此時(shí),運(yùn)行程序,在文本框中輸入內(nèi)容,點(diǎn)擊按鈕就可以看到生成的二維碼:
仔細(xì)的話你會(huì)發(fā)現(xiàn)這里的二維碼比較模糊,這是由于生成的二維碼尺寸較小,在imageView中顯示時(shí)被拉伸導(dǎo)致的。下面我們就通過調(diào)整二維碼的縮放來解決圖像模糊的問題。
修改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)]; // 將調(diào)整后的CIImage對象轉(zhuǎn)換成UIImage對象,并顯示在圖像視圖中 self.imageView.image = [UIImage imageWithCIImage:transformedImage]; }
再次運(yùn)行,你會(huì)看到一張清晰的二維碼:
2.3.2 刪除二維碼圖像
在這個(gè)demo中,按鈕具有雙重作用:即生成二維碼和刪除二維碼。因此需要在clickButton:
方法中先判斷二維碼圖像是否存在:
如果不存在,點(diǎn)擊按鈕生成一張二維碼圖像,按鈕的標(biāo)題變?yōu)?quot;Clear"。
如果存在,點(diǎn)擊按鈕刪除二維碼圖像,按鈕的標(biāo)題變?yōu)?quot;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
方法并實(shí)現(xiàn)它:
- (void)clearQRCodeImage { self.imageView.image = nil; self.qrcodeImage = nil; self.textField.text = nil; }
至此,二維碼的生成和刪除已基本完成,但為了有良好的體驗(yàn),我們還需要考慮下面的情況:
在文本框未輸入的情況下點(diǎn)擊按鈕是否生成二維碼。
切換按鈕時(shí)文本框的響應(yīng)狀態(tài)以及鍵盤出現(xiàn)與消失。
滑動(dòng)條的顯示和隱藏。
于是,在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; }
最后,考慮到程序啟動(dòng)時(shí)滑動(dòng)條不應(yīng)該顯示(滑動(dòng)條只在生成二維碼時(shí)出現(xiàn)),還需要在viewDidLoad
方法中設(shè)置其hidden
屬性:
- (void)viewDidLoad { [super viewDidLoad]; self.slider.hidden = YES; }
可以再次運(yùn)行試下。
2.3.3 縮放二維碼圖像
縮放顯示的二維碼主要是通過拖動(dòng)滑動(dòng)條縮放image View來完成的。在實(shí)現(xiàn)部分找到changeScale:
方法,并添加代碼下面的代碼即可:
- (IBAction)changeScale:(id)sender { self.imageView.transform = CGAffineTransformMakeScale((CGFloat)self.slider.value, (CGFloat)self.slider.value); }
需要注意的是,self.slider.value
是float
類型,而CGAffineTransformMakeScale
方法的參數(shù)是CGFloat
類型,因此在上面的代碼中進(jìn)行了類型轉(zhuǎn)換。
2.3.4 保存二維碼圖像
將生成的二維碼圖片保存到相機(jī)膠卷相冊主要是使用 UIImageWriteToSavedPhotosAlbum 函數(shù)來實(shí)現(xiàn)的。其完整聲明如下:
復(fù)制代碼 代碼如下:
void UIImageWriteToSavedPhotosAlbum(UIImage *image, id completionTarget, SEL completionSelector, void *contextInfo);
其中各參數(shù)及含義:
image
:表示要保存到相冊的圖像。
completionTarget
:可選的參數(shù),表示圖片保存后,調(diào)用完成選擇器(completionSelector)的對象。
completionSelector
:可選的方法,表示圖片保存后,completionTarget對象要調(diào)用的方法(即回調(diào)方法)。該方法應(yīng)符合以下簽名:
- (void)image:(UIImage *)image didFinishSavingWithError:(NSError *)error contextInfo:(void *)contextInfo;
contextInfo
:可選的參數(shù),用于提供一個(gè)上下文信息以通過參數(shù)傳遞給completionSelector。
在這里我們的大致思路是:首先在imageView中添加單擊手勢,當(dāng)用戶點(diǎn)擊二維碼圖像時(shí)會(huì)彈出一個(gè)提示框詢問是否保存,如果用戶點(diǎn)擊保存按鈕,那么就將二維碼保存到相冊中。下面是具體實(shí)現(xiàn):
打開Main.storyboard文件,從對象庫中找到點(diǎn)擊手勢(Tap Gesture Recognizer),將其添加到視圖控制器的Image View上,完成之后會(huì)在控制器的頂部看到它:
打開輔助編輯器,將其連接到代碼中:
為了使image View能響應(yīng)手勢操作,需要在viewDidLoad
中設(shè)置image View的userInteractionEnabled
屬性:
- (void)viewDidLoad { ... self.imageView.userInteractionEnabled = YES; }
然后在實(shí)現(xiàn)部分找到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]; }
這時(shí)編譯器會(huì)有紅色警告提示saveQRCodeImage
方法未聲明。接下來我們就在實(shí)現(xiàn)部分添加該方法來實(shí)現(xiàn)二維碼的保存:
- (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對象轉(zhuǎn)換來的,是保存不到相冊的,需要先在圖形上下文中繪制一下,生成一個(gè)新的圖像,然后才能保存。
此時(shí),運(yùn)行程序,點(diǎn)擊生成的二維碼圖像你會(huì)看到下面的效果:
但是點(diǎn)擊Save按鈕時(shí),程序會(huì)崩潰,在控制臺(tái)會(huì)看到下面的消息:
This app has crashed because it attempted to access privacy-sensitive data without a usage description. The app's Info.plist must contain an NSPhotoLibraryAddUsageDescription key with a string value explaining to the user how the app uses this data.
這是因?yàn)閕OS要求應(yīng)用程序開發(fā)者在允許訪問相冊之前要先獲得用戶的許可。為此,我們必須在Info.plist
文件中添加名為NSPhotoLibraryAddUsageDescription
的鍵,并為其添加相應(yīng)的描述:
問題修復(fù)完成!再次運(yùn)行,點(diǎn)擊保存按鈕,打開相冊應(yīng)用,你會(huì)看到剛才保存的二維碼:
到目前為止,我們的工作已基本完成,但是為了更完美一些,最好是在點(diǎn)擊保存按鈕之后能夠收到是否保存成功的反饋。所以需要在saveQRCodeImage
方法中更改UIImageWriteToSavedPhotosAlbum
函數(shù)的參數(shù):
- (void)saveQRCodeImage { ... // 保存圖像 UIImageWriteToSavedPhotosAlbum(self.imageView.image, self, @selector(image:didFinishSavingWithError:contextInfo:), nil); }
然后添加image:didFinishSavingWithError:contextInfo:
方法,并在該方法內(nèi)創(chuàng)建alert View來顯示二維碼的保存狀態(tài):
- (void)image:(UIImage *)image didFinishSavingWithError:(NSError *)error contextInfo:(void *)contextInfo { NSString *title; NSString *message; if (!error) { title = @"Success!"; message = @"The QRCode image saved successfully."; } else { title = @"Failed!"; message = @"The QRCode image saved unsuccessfully, please try again later."; } // 使用alert view顯示二維碼保存狀態(tài) UIAlertController *alert = [UIAlertController alertControllerWithTitle:title message:message preferredStyle:UIAlertControllerStyleAlert]; UIAlertAction *action = [UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:nil]; [alert addAction:action]; [self presentViewController:alert animated:YES completion:nil]; }
關(guān)于怎么在iOS中使用CIFilter生成一個(gè)二維碼就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,可以學(xué)到更多知識。如果覺得文章不錯(cuò),可以把它分享出去讓更多的人看到。
另外有需要云服務(wù)器可以了解下創(chuàng)新互聯(lián)建站www.rwnh.cn,海內(nèi)外云服務(wù)器15元起步,三天無理由+7*72小時(shí)售后在線,公司持有idc許可證,提供“云服務(wù)器、裸金屬服務(wù)器、高防服務(wù)器、香港服務(wù)器、美國服務(wù)器、虛擬主機(jī)、免備案服務(wù)器”等云主機(jī)租用服務(wù)以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡單易用、服務(wù)可用性高、性價(jià)比高”等特點(diǎn)與優(yōu)勢,專為企業(yè)上云打造定制,能夠滿足用戶豐富、多元化的應(yīng)用場景需求。
網(wǎng)頁標(biāo)題:怎么在iOS中使用CIFilter生成一個(gè)二維碼-創(chuàng)新互聯(lián)
本文網(wǎng)址:http://www.rwnh.cn/article10/hsjdo.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供企業(yè)建站、小程序開發(fā)、Google、服務(wù)器托管、動(dòng)態(tài)網(wǎng)站、面包屑導(dǎo)航
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)
猜你還喜歡下面的內(nèi)容