亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 系統 > iOS > 正文

iOS使用CIFilter生成二維碼

2019-10-21 18:42:34
字體:
來源:轉載
供稿:網友

二維碼(Quick Response Code,簡稱QR Code)是由水平和垂直兩個方向上的線條設計而成的一種二維條形碼(barcode)。可以編碼網址、電話號碼、文本等內容,能夠存儲大量的數據信息。自iOS 7以來,二維碼的生成和讀取只需要使用Core Image框架和AVFoundation框架就能輕松實現。在這里,我們主要介紹二維碼的生成。關于二維碼的讀取,在 使用AVFoundation讀取二維碼 文章中有詳細介紹。

iOS,生成二維碼,CIFilter生成二維碼

1 二維碼的生成

生成一個二維碼也就是根據提供的數據內容轉換成一張二維碼圖像。從iOS 7開始,我們只需要使用CIFilter中的CIQRCodeGenerator就可以輕易實現。只不過這樣生成的二維碼圖像是一個CIImage對象,如果要在圖像視圖中顯示,需要將其轉換為UIImage對象。具體步驟如下:

①、使用名為 CIQRCodeGenerator 的過濾器創建一個CIFilter對象。

CIFilter *filter = [CIFilter filterWithName:@"CIQRCodeGenerator"]

②、為CIFilter對象設置 inputMessageinputCorrectionLevel 參數。

  1. inputMessage :是一個NSData對象,用于表示被編碼的數據。對于字符串或者URL,需要使用NSISOLatin1StringEncoding字符串編碼將其轉換為NSData對象。要注意的是,NSISOLatin1StringEncoding編碼對于中文或表情無法生成,需要的話可以使用NSUTF8StringEncoding 替換。
  2. 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 應用示例

下面,我們就做一個如下圖所示的二維碼生成器:

iOS,生成二維碼,CIFilter生成二維碼

其中主要實現的功能有:

  1. 生成和刪除二維碼。
  2. 通過滑動條對二維碼圖像進行縮放。
  3. 將二維碼保存到相冊。

2.1 創建項目

打開 Xcode ,創建一個新的項目( File/New/Project.. .),選擇 iOS 一欄下的 Application 中的 Single View Application 模版,然后點擊 Next ,填寫項目選項。在 Product Name 中填寫 QRCodeGeneratorDemo ,選擇 Objective-C 語言,點擊 Nex t,選擇文件位置,并單擊 Create 創建項目。

iOS,生成二維碼,CIFilter生成二維碼

2.2 構建界面

打開 Main.storyboard 文件,在當前控制器中嵌入導航控制器,并添加標題 QR Code Generator

iOS,生成二維碼,CIFilter生成二維碼

在視圖控制器中添加文本框、按鈕、圖像視圖等,布局如下:

iOS,生成二維碼,CIFilter生成二維碼

其中各元素及作用:

  1. Text Field:用于輸入想要轉換為二維碼的數據內容,包括文本或URL字符串。
  2. Button:在這里具有雙重作用,用于生成和清除二維碼。
  3. Image View:用于顯示生成的二維碼圖像。
  4. Slider:用來縮放生成的二維碼圖像。

打開輔助編輯器,將storyboard中的元素連接到代碼中:

iOS,生成二維碼,CIFilter生成二維碼

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];}

此時,運行程序,在文本框中輸入內容,點擊按鈕就可以看到生成的二維碼:

iOS,生成二維碼,CIFilter生成二維碼

仔細的話你會發現這里的二維碼比較模糊,這是由于生成的二維碼尺寸較小,在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];}

再次運行,你會看到一張清晰的二維碼:

iOS,生成二維碼,CIFilter生成二維碼

2.3.2 刪除二維碼圖像

在這個demo中,按鈕具有雙重作用:即生成二維碼和刪除二維碼。因此需要在 clickButton: 方法中先判斷二維碼圖像是否存在:

  1. 如果不存在,點擊按鈕生成一張二維碼圖像,按鈕的標題變為" Clear "。
  2. 如果存在,點擊按鈕刪除二維碼圖像,按鈕的標題變為" 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;}

至此,二維碼的生成和刪除已基本完成,但為了有良好的體驗,我們還需要考慮下面的情況:

  1. 在文本框未輸入的情況下點擊按鈕是否生成二維碼。
  2. 切換按鈕時文本框的響應狀態以及鍵盤出現與消失。
  3. 滑動條的顯示和隱藏。

于是,在 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 縮放二維碼圖像

縮放顯示的二維碼主要是通過拖動滑動條縮放image View來完成的。在實現部分找到 changeScale: 方法,并添加代碼下面的代碼即可:

- (IBAction)changeScale:(id)sender{  self.imageView.transform = CGAffineTransformMakeScale((CGFloat)self.slider.value, (CGFloat)self.slider.value);}

需要注意的是, self.slider.valuefloat 類型,而 CGAffineTransformMakeScale 方法的參數是 CGFloat 類型,因此在上面的代碼中進行了類型轉換。

2.3.4 保存二維碼圖像

將生成的二維碼圖片保存到相機膠卷相冊主要是使用 UIImageWriteToSavedPhotosAlbum 函數來實現的。其完整聲明如下:

 

復制代碼 代碼如下:

void UIImageWriteToSavedPhotosAlbum(UIImage *image, id completionTarget, SEL completionSelector, void *contextInfo);

 

其中各參數及含義:

image :表示要保存到相冊的圖像。

completionTarget :可選的參數,表示圖片保存后,調用完成選擇器(completionSelector)的對象。

completionSelector :可選的方法,表示圖片保存后,completionTarget對象要調用的方法(即回調方法)。該方法應符合以下簽名:

- (void)image:(UIImage *)image  didFinishSavingWithError:(NSError *)error         contextInfo:(void *)contextInfo;

contextInfo :可選的參數,用于提供一個上下文信息以通過參數傳遞給completionSelector。

在這里我們的大致思路是:首先在imageView中添加單擊手勢,當用戶點擊二維碼圖像時會彈出一個提示框詢問是否保存,如果用戶點擊保存按鈕,那么就將二維碼保存到相冊中。下面是具體實現:

打開 Main.storyboard 文件,從對象庫中找到點擊手勢(Tap Gesture Recognizer),將其添加到視圖控制器的Image View上,完成之后會在控制器的頂部看到它:

iOS,生成二維碼,CIFilter生成二維碼

打開輔助編輯器,將其連接到代碼中:

iOS,生成二維碼,CIFilter生成二維碼

為了使image View能響應手勢操作,需要在 viewDidLoad 中設置image View的 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對象轉換來的,是保存不到相冊的,需要先在圖形上下文中繪制一下,生成一個新的圖像,然后才能保存。

此時,運行程序,點擊生成的二維碼圖像你會看到下面的效果:

iOS,生成二維碼,CIFilter生成二維碼

但是點擊 Save 按鈕時,程序會崩潰,在控制臺會看到下面的消息:

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.

這是因為iOS要求應用程序開發者在允許訪問相冊之前要先獲得用戶的許可。為此,我們必須在 Info.plist 文件中添加名為 NSPhotoLibraryAddUsageDescription 的鍵,并為其添加相應的描述:

iOS,生成二維碼,CIFilter生成二維碼

問題修復完成!再次運行,點擊保存按鈕,打開相冊應用,你會看到剛才保存的二維碼:

iOS,生成二維碼,CIFilter生成二維碼

到目前為止,我們的工作已基本完成,但是為了更完美一些,最好是在點擊保存按鈕之后能夠收到是否保存成功的反饋。所以需要在 saveQRCodeImage 方法中更改 UIImageWriteToSavedPhotosAlbum 函數的參數:

- (void)saveQRCodeImage{  ...    // 保存圖像  UIImageWriteToSavedPhotosAlbum(self.imageView.image, self, @selector(image:didFinishSavingWithError:contextInfo:), nil);}

然后添加 image:didFinishSavingWithError:contextInfo: 方法,并在該方法內創建alert View來顯示二維碼的保存狀態:

- (void)image:(UIImage *)image didFinishSavingWithError:(NSError *)error contextInfo:(void *)contextInfo{  NSString *title;  NSString *message;    if (!error) {    message = @"The QRCode image saved successfully.";  }  else {    message = @"The QRCode image saved unsuccessfully, please try again later.";  }    // 使用alert view顯示二維碼保存狀態  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];}

運行程序,測試一下效果:

iOS,生成二維碼,CIFilter生成二維碼

至此,我們的二維碼生成器已經全部完成,如果需要完整代碼,可以下載 QRCodeGeneratorDemo 查看。

3 參考資料

CIFilter - Core Image | Apple Developer Documentation

Building a QR Code Generator with Core Image Filters

CIQRCodeGenerator

HOW TO SAVE/LOAD IMAGE/VIDEOS FROM CAMERA ROLL – XCODE IOS

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持VEVB武林網。


注:相關教程知識閱讀請移步到IOS開發頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
69视频在线播放| 国产成人精品免高潮在线观看| 中文字幕v亚洲ⅴv天堂| 精品视频—区二区三区免费| 91国自产精品中文字幕亚洲| 九九热这里只有精品6| 精品国产户外野外| 国产日韩在线精品av| 亚洲精品动漫久久久久| 国产精品天天狠天天看| 综合国产在线观看| 日韩美女激情视频| 黄色成人在线免费| 久久人人爽人人爽人人片亚洲| 国产97色在线| 日韩精品久久久久| 亚洲精品二三区| 日韩精品亚洲视频| 国产精品人成电影在线观看| www日韩欧美| 高清欧美电影在线| 精品福利在线看| 久久在线免费视频| 亚洲国产91色在线| 久久久久久有精品国产| 91精品久久久久久久久青青| 欧美性极品xxxx娇小| 欧美刺激性大交免费视频| 欧美美最猛性xxxxxx| 亚洲国产精品高清久久久| 91免费精品国偷自产在线| 91精品国产777在线观看| 亚洲欧美制服丝袜| 91午夜理伦私人影院| 亚洲区免费影片| 亚洲少妇中文在线| 最新中文字幕亚洲| 久久久久久久久久久免费| 日韩欧美在线第一页| 91欧美精品午夜性色福利在线| 亚洲free性xxxx护士白浆| 尤物九九久久国产精品的分类| 亚洲第一中文字幕在线观看| 这里只有精品丝袜| 日韩中文在线观看| 色妞欧美日韩在线| 欧美视频在线观看 亚洲欧| 麻豆乱码国产一区二区三区| 亚洲成人1234| 日韩av理论片| 欧美日韩国产成人高清视频| 欧美一级片免费在线| 国产精品第2页| 亚洲视频在线观看视频| 91久久精品久久国产性色也91| 久久久久久高潮国产精品视| 精品一区二区三区四区在线| 中日韩美女免费视频网站在线观看| 91国偷自产一区二区三区的观看方式| 91精品国产成人| 成人黄色av网| 欧美性猛交xxxx偷拍洗澡| 国产成人精品网站| 精品日韩中文字幕| 国模叶桐国产精品一区| 欧美xxxx做受欧美| 亚洲国产一区自拍| 91精品国产免费久久久久久| 欧美日韩国产专区| 国产日韩中文在线| 欧美一级电影久久| 日产日韩在线亚洲欧美| 亚洲成人1234| 美日韩精品视频免费看| 国产精品久久综合av爱欲tv| 欧美一区二区.| 国产精品1区2区在线观看| 久久久久久久久久久av| 日韩欧美一区二区三区| 国产一区二区三区视频免费| 亚洲free性xxxx护士hd| 久久亚洲精品小早川怜子66| 国产男女猛烈无遮挡91| 蜜臀久久99精品久久久久久宅男| 欧美在线性视频| 日韩美女在线观看一区| 国产亚洲美女久久| 日韩精品免费一线在线观看| 久久国产精品久久久久| 亚洲最大的成人网| 一本色道久久综合亚洲精品小说| 亚洲国产一区二区三区在线观看| 久久久久久久久久久成人| 亚洲字幕一区二区| 91大神福利视频在线| 精品久久久久久久久国产字幕| 日韩成人在线电影网| 国产欧美一区二区白浆黑人| 国产成人综合久久| 日本欧美国产在线| 2020久久国产精品| 亚洲精品成人久久久| 精品国产区一区二区三区在线观看| 亚洲综合中文字幕68页| 亚洲国产精品资源| 国产精品视频成人| 欧美日韩性生活视频| 中文字幕欧美日韩精品| 91精品国产99| 日韩在线观看免费全| 日韩专区中文字幕| 国产精品日韩电影| 久久久久亚洲精品| 国产精品永久免费| 久久免费精品日本久久中文字幕| 日韩电视剧在线观看免费网站| 日韩精品视频免费在线观看| 欧美在线影院在线视频| 日本伊人精品一区二区三区介绍| 亚洲肉体裸体xxxx137| 成人免费黄色网| 亚洲男人第一网站| 国产精品wwww| 国产主播精品在线| 日韩精品一二三四区| 日本一本a高清免费不卡| 伊人久久久久久久久久久| 亚洲摸下面视频| 国产精品成熟老女人| 国产日韩在线观看av| 亚洲网在线观看| 亚洲成人久久一区| 一道本无吗dⅴd在线播放一区| 国产91九色视频| 日本高清+成人网在线观看| 韩国一区二区电影| 青青久久av北条麻妃海外网| 久久久久久69| 性欧美在线看片a免费观看| 91久久久在线| 黑人巨大精品欧美一区二区| 欧美日在线观看| 精品激情国产视频| 国产丝袜一区二区三区免费视频| 亚洲成人三级在线| 亚洲欧美日韩一区在线| 亚洲成人久久久| 日韩av电影免费观看高清| 亚洲精品国产福利| 亚洲欧洲在线观看| 久久久电影免费观看完整版| 91在线免费视频| 国产一区二区三区毛片| 欧美极度另类性三渗透| 久久人人97超碰精品888| 最近2019中文字幕在线高清| 午夜精品久久久久久久99黑人| 这里只有精品久久| 亚洲欧美国产另类| 国产欧美中文字幕| 久久久免费av| 久久亚洲综合国产精品99麻豆精品福利| 国内精品久久久久久| 中国日韩欧美久久久久久久久|