iOS原生QRコード生成&スキャン
8955 ワード
この機能をスキャンすると、私たちはよく知らないわけではありません.微信QQに友达を追加してスキャンし、道端で普及したスキャンをして、食事をしてお金を払ってスキャンします.このスイープアプリの場所は本当に多いようですね.携帯電話を開けてインストールしたアプリを見てみると、ソーシャルアプリがスキャンされ、支払いアプリがスキャンされ、ブラウザもスキャンされています.この掃除は軽視できないようだ.いつあなたのプロジェクトの中であなたのbossはあなたに彼に掃除の機能を追加するかどうか分かりません!iOSの開発でスキャンを行うのは難しくありませんが、QRコード(QRCode)を処理する必要があります.iOS 7の前にサードパーティ製ライブラリZBarとZXingを借りる必要があります.iOS 7以降はAPI持参で簡単にできます.プロジェクトに膨大なサードパーティ製ライブラリを導入したり、コンパイルに問題が発生する心配はありません.
QRコードとは
2次元バーコードとは、1次元バーコードに基づいて別の1次元の可読性を有するバーコードを拡張し、白黒矩形パターンを用いてバイナリデータを表し、デバイスにスキャンされた後、その中に含まれる情報を取得することができる.ウィキペディア
詳細な生成の詳細と原理はQRコードの生成の詳細と原理のこの文章を見ることができます.
スキャンQRコード
まず、具体的な手順を考えてみましょう.大体の流れは、1.デバイスのカメラを開く-->2.QRコード画像のキャプチャを行う-->3.キャプチャされた画像を取得して解析を行う-->4.解析結果を取得して後続の処理を行うことです.これらのプロセスは
キャプチャの設定は完了していますが、「スキャン」を開始していません.スキャンを完了するには、
次に、すぐにセッションを開始する(スキャンを開始する)のではなく、セッションの
次にsessionの
ユーザーに配慮するには、照明の機能を加えたり、興味エリアを設定したりする必要があります.興味領域 を設ける.
微信のスキャンを使用すると、スキャンインタフェースの真ん中に矩形の限定ボックスがあり、このボックスが興味領域であることがわかります.この関心領域は照明機能 を加える.
照明機能を加えることで、照明条件が悪い場合にスキャン操作を円滑に行うことができます.コードは以下の通りです.
画像からQRコードを読み込む
画像からQRコードを直接読み取る機能はiOS 7ではアップルでは実現していないが、iOSではこの機能が埋まっている.主にCoreImageを読み取ります.
くだらないことは言わないで、直接コードをつけます.
アルバムから写真を取るという話がある以上、ついでにアルバムから写真を取ることも話しましょう.
アルバムから写真を取得するには主に
ライブラリから写真を選択した後、
QRコードの生成
QRコードを生成するには、画像からQRコードを読み出すのと同様に
もちろん、このコードを書きたくない場合は、軽量レベルのオープンソースlibqrencodeを使用して実現することもできます.UIImage+MDQRCodeという拡張子を導入すると、UIImageのクラスメソッドを使用して呼び出すことができます.
QRCScanner
上のコードさえ少しも書きたくない場合は、一言でスキャン機能を統合したい場合は、
QRコードとは
2次元バーコードとは、1次元バーコードに基づいて別の1次元の可読性を有するバーコードを拡張し、白黒矩形パターンを用いてバイナリデータを表し、デバイスにスキャンされた後、その中に含まれる情報を取得することができる.ウィキペディア
詳細な生成の詳細と原理はQRコードの生成の詳細と原理のこの文章を見ることができます.
スキャンQRコード
まず、具体的な手順を考えてみましょう.大体の流れは、1.デバイスのカメラを開く-->2.QRコード画像のキャプチャを行う-->3.キャプチャされた画像を取得して解析を行う-->4.解析結果を取得して後続の処理を行うことです.これらのプロセスは
AVFoundation
というライブラリを使用する必要があります.インポートに注意してください.// AVCaptureDevice ,
AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
// AVCaptureDeviceInput , ' '
AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:_device error:nil];
// , AVCaptureMetadataOutput ' ' ,
AVCaptureMetadataOutput *output = [[AVCaptureMetadataOutput alloc]init];
// ,
[output setMetadataObjectsDelegate:self queue:dispatch_get_main_queue()];
// , AVMetadataObjectTypeQRCode , 。
output.metadataObjectTypes = @[AVMetadataObjectTypeEAN13Code,
AVMetadataObjectTypeEAN8Code,
AVMetadataObjectTypeCode128Code,
AVMetadataObjectTypeQRCode];
キャプチャの設定は完了していますが、「スキャン」を開始していません.スキャンを完了するには、
AVCaptureSession
というクラスが必要です.このセッションクラスは、スキャンを1回のセッションと見なし、セッションが開始された後に「スキャン」が開始されます.具体的なコードは次のとおりです.AVCaptureSession *session = [[AVCaptureSession alloc]init];
[session setSessionPreset:AVCaptureSessionPresetHigh];//
if ([session canAddInput:input]){
[session addInput:input];//
}
if ([session canAddOutput:output]){
[session addOutput:output];//
}
次に、すぐにセッションを開始する(スキャンを開始する)のではなく、セッションの
startRunning
メソッドを呼び出すと、画面が黒くなっていることがわかります.カメラのファインダーのサイズが設定されていないためです.ファインダーを設置するにはAVCaptureVideoPreviewLayer
というクラスが必要です.具体的なコードは以下の通りです.AVCaptureVideoPreviewLayer *preview =[AVCaptureVideoPreviewLayer layerWithSession:session];
preview.videoGravity = AVLayerVideoGravityResize;
[preview setFrame:self.view.bounds];// frame
[self.view.layer insertSublayer:preview atIndex:0];
次にsessionの
startRunning
メソッドを呼び出すことができます.このとき、私たちのスキャンは本当に始まります.スキャンの結果を得るには、sessionを実装するエージェントメソッド- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:(NSArray *)metadataObjects fromConnection:(AVCaptureConnection *)connection
が必要であり、コードは以下の通りである.- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:(NSArray *)metadataObjects fromConnection:(AVCaptureConnection *)connection
{
[self.session stopRunning];//
[self.preview removeFromSuperlayer];//
if (metadataObjects.count > 0) {
AVMetadataMachineReadableCodeObject *obj = metadataObjects[0];
NSString *result = obj.stringValue;//
// ...
}
}
ユーザーに配慮するには、照明の機能を加えたり、興味エリアを設定したりする必要があります.
微信のスキャンを使用すると、スキャンインタフェースの真ん中に矩形の限定ボックスがあり、このボックスが興味領域であることがわかります.この関心領域は
AVCaptureMetadataOutput
のrectOfInterest
属性である.rectOfInterest
の値の範囲はすべて0-1で、実際のサイズではなく比例して値を取るので、設定するときに注意しなければならない点です.また、rectOfInterest
は横スクリーンで計算されるので、縦スクリーンの場合はx軸とy軸を交換します.コードは次のとおりです.CGSize size = self.view.bounds.size;
CGSize transparentAreaSize = CGSizeMake(200,200);
CGRect cropRect = CGRectMake((size.width - transparentAreaSize.width)/2, (size.height - transparentAreaSize.height)/2, transparentAreaSize.width, transparentAreaSize.height);
output.rectOfInterest = CGRectMake(cropRect.origin.y/size.width,
cropRect.origin.x/size.height,
cropRect.size.height/size.height,
cropRect.size.width/size.width);
照明機能を加えることで、照明条件が悪い場合にスキャン操作を円滑に行うことができます.コードは以下の通りです.
AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
NSError *error;
if (device.hasTorch) { //
BOOL b = [device lockForConfiguration:&error];
if (!b) {
if (error) {
NSLog(@"lock torch configuration error:%@", error.localizedDescription);
}
return;
}
device.torchMode = (device.torchMode == AVCaptureTorchModeOff ? AVCaptureTorchModeOn : AVCaptureTorchModeOff);
[device unlockForConfiguration];
}
画像からQRコードを読み込む
画像からQRコードを直接読み取る機能はiOS 7ではアップルでは実現していないが、iOSではこの機能が埋まっている.主にCoreImageを読み取ります.
くだらないことは言わないで、直接コードをつけます.
+ (NSString *)scQRReaderForImage:(UIImage *)qrimage{
CIContext *context = [CIContext contextWithOptions:nil];
CIDetector *detector = [CIDetector detectorOfType:CIDetectorTypeQRCode context:context options:@{CIDetectorAccuracy:CIDetectorAccuracyHigh}];
CIImage *image = [CIImage imageWithCGImage:qrimage.CGImage];
NSArray *features = [detector featuresInImage:image];
CIQRCodeFeature *feature = [features firstObject];
NSString *result = feature.messageString;
return result;
}
アルバムから写真を取るという話がある以上、ついでにアルバムから写真を取ることも話しましょう.
アルバムから写真を取得するには主に
UIImagePickerController
が使われています.これはアップルが私たちに分けてくれたアルバム選択のコントローラです.実現するのも簡単です.- (void)readerImage{
UIImagePickerController *photoPicker = [[UIImagePickerController alloc] init];
photoPicker.delegate = self;
photoPicker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
photoPicker.view.backgroundColor = [UIColor whiteColor];
[self presentViewController:photoPicker animated:YES completion:NULL];
}
ライブラリから写真を選択した後、
UIImagePickerController
を呼び出すエージェントメソッドを使用して選択した写真を取得します.- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info{
[self dismissViewControllerAnimated:YES completion:^{
//code is here ...
}];
UIImage *srcImage = [info objectForKey:UIImagePickerControllerOriginalImage];
NSString *result = [QRCScanner scQRReaderForImage:srcImage];//
[self.navigationController popViewControllerAnimated:YES];
}
QRコードの生成
QRコードを生成するには、画像からQRコードを読み出すのと同様に
CoreImage
を使用します.具体的な手順は、次のとおりです.- (UIImage *)makeQRCodeForString(NSString *)string{
NSString *text = string;
NSData *stringData = [text dataUsingEncoding: NSUTF8StringEncoding];
//
CIFilter *qrFilter = [CIFilter filterWithName:@"CIQRCodeGenerator"];
[qrFilter setValue:stringData forKey:@"inputMessage"];
[qrFilter setValue:@"M" forKey:@"inputCorrectionLevel"];
//
UIColor *onColor = [UIColor redColor];
UIColor *offColor = [UIColor blueColor];
// , QRCode
CIFilter *colorFilter = [CIFilter filterWithName:@"CIFalseColor"
keysAndValues:
@"inputImage",qrFilter.outputImage,
@"inputColor0",[CIColor colorWithCGColor:onColor.CGColor],
@"inputColor1",[CIColor colorWithCGColor:offColor.CGColor],
nil];
//
CIImage *qrImage = colorFilter.outputImage;
CGSize size = CGSizeMake(300, 300);
CGImageRef cgImage = [[CIContext contextWithOptions:nil] createCGImage:qrImage fromRect:qrImage.extent];
UIGraphicsBeginImageContext(size);
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetInterpolationQuality(context, kCGInterpolationNone);
CGContextScaleCTM(context, 1.0, -1.0);// QRCode ,
CGContextDrawImage(context, CGContextGetClipBoundingBox(context), cgImage);
UIImage *codeImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
CGImageRelease(cgImage);
return [UIImage imageWithCIImage:qrImage];
}
もちろん、このコードを書きたくない場合は、軽量レベルのオープンソースlibqrencodeを使用して実現することもできます.UIImage+MDQRCodeという拡張子を導入すると、UIImageのクラスメソッドを使用して呼び出すことができます.
+ (UIImage *)mdQRCodeForString:(NSString *)qrString size:(CGFloat)size;
+ (UIImage *)mdQRCodeForString:(NSString *)qrString size:(CGFloat)size fillColor:(UIColor *)fillColor;
QRCScanner
上のコードさえ少しも書きたくない場合は、一言でスキャン機能を統合したい場合は、
QRCScanner
、アドレスポイントを使用することができます.