{"id":176,"date":"2015-12-03T17:54:08","date_gmt":"2015-12-03T09:54:08","guid":{"rendered":"http:\/\/www.yusian.com\/blog\/?p=176"},"modified":"2016-07-14T22:42:52","modified_gmt":"2016-07-14T14:42:52","slug":"%e5%88%a9%e7%94%a8%e7%b3%bb%e7%bb%9fav%e6%a1%86%e6%9e%b6%e5%88%b6%e4%bd%9c%e5%ae%9e%e7%8e%b0%e6%89%ab%e4%b8%80%e6%89%ab%e5%8a%9f%e8%83%bd%ef%bc%88%e4%b8%80%e8%a1%8c%e4%bb%a3%e7%a0%81%e6%90%9e%e5%ae%9a","status":"publish","type":"post","link":"https:\/\/www.yusian.com\/blog\/project\/2015\/12\/03\/175408176.html","title":{"rendered":"\u5229\u7528\u7cfb\u7edfAV\u6846\u67b6\u5236\u4f5c\u5b9e\u73b0\u626b\u4e00\u626b\u529f\u80fd\uff08\u4e00\u884c\u4ee3\u7801\u641e\u5b9a\uff09"},"content":{"rendered":"<p><strong>1\u3001\u5148\u4e0a\u56fe\u770b\u770b\u6548\u679c<\/strong><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/www.yusian.com\/blog\/wp-content\/uploads\/2016\/07\/Screen-Shot-2015-12-03-at-\u4e0b\u53485.32.13.jpg\" alt=\"Screen-Shot-2015-12-03-at-\u4e0b\u53485.32.13\" width=\"320\" height=\"568\" class=\"alignnone size-full wp-image-177\" \/><\/p>\n<p><strong>2\u3001\u8bbe\u8ba1\u601d\u8def<\/strong><br \/>\n2.1\u3001\u5229\u7528AVCaptureMetadataOutput\u56fa\u6709\u7684\u8f93\u51fa\u5c5e\u6027\uff0c\u80fd\u591f\u8f93\u51fa\u4e8c\u7ef4\u7801\u53ca\u6761\u5f62\u7801\u7684\u89e3\u6790\u7ed3\u679c<br \/>\n2.2\u3001\u5229\u7528Quartz 2D\u7ed8\u51fa\u57fa\u672c\u626b\u63cf\u754c\u9762\uff0c\u7ed3\u5408\u52a8\u753b\u6548\u679c\uff0c\u7b80\u5355\u53c8\u9ad8\u6548\uff012.3\u3001\u53ea\u9700\u4e24\u4e2a\u7c7b\uff0c\u4e00\u4e2a\u63a7\u5236\u5668\uff0c\u4e00\u4e2a\u89c6\u56fe\uff1aSAScanCtrl   SAScan<br \/>\n2.3\u3001\u5176\u4ed6\u5185\u5bb9\u5728\u4ee3\u7801\u4e2d\u7ed9\u51fa\u76f8\u5173\u6ce8\u91ca\u8bf4\u660e<!--more--><\/p>\n<p><strong>3\u3001\u90e8\u5206\u4ee3\u7801<\/strong><br \/>\nSAScanCtrl.m<\/p>\n<pre lang=\"objc\" line=\"1\">\/\/\n\/\/? SAScanCtrl.m\n\/\/\n\/\/\n\/\/? Created by \u4f59\u897f\u5b89 on 15\/12\/3.\n\/\/? Copyright ? 2015\u5e74 Sian. All rights reserved.\n\/\/\n?\n#import \"SAScanCtrl.h\"\n#import \"SAScan.h\"\n#import <AVFoundation\/AVFoundation.h>\n?\n@interface SAScanCtrl ()<AVCaptureMetadataOutputObjectsDelegate>\n?\n@property (nonatomic, strong) AVCaptureSession *session;\n?\n@property (nonatomic, strong) AVAudioPlayer??? *player;\n?\n@property (nonatomic, strong) SAScan?????????? *scan;\n?\n@end\n?\n@implementation SAScanCtrl\n?\n- (instancetype)initWithBlock:(SAScanBlock)block\n{\n????if (self = [super init]){\n????????self.block = block;\n????}\n????return self;\n}\n?\n- (void)viewDidLoad\n{\n????[super viewDidLoad];\n????[self.navigationItem setTitle:@\"\u626b\u4e00\u626b\"];\n?????\n????AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];\n????AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:device error:nil];\n????AVCaptureMetadataOutput *output = [[AVCaptureMetadataOutput alloc]init];\n????[output setMetadataObjectsDelegate:self queue:dispatch_get_main_queue()];?? \/\/ \u8bbe\u7f6e\u4ee3\u7406 \u5728\u4e3b\u7ebf\u7a0b\u91cc\u5237\u65b0\n????[output setRectOfInterest:CGRectMake(0.12 , 0.12, 0.8, 0.8)];\n?????\n????\/\/\u521d\u59cb\u5316\u94fe\u63a5\u5bf9\u8c61\n????self.session = [[AVCaptureSession alloc] init];\n????[self.session addInput:input];\n????[self.session addOutput:output];\n????[self.session setSessionPreset:AVCaptureSessionPresetHigh];\n????\/\/\u8bbe\u7f6e\u626b\u7801\u652f\u6301\u7684\u7f16\u7801\u683c\u5f0f(\u5982\u4e0b\u8bbe\u7f6e\u6761\u5f62\u7801\u548c\u4e8c\u7ef4\u7801\u517c\u5bb9)\n????[output setMetadataObjectTypes:@[AVMetadataObjectTypeQRCode,AVMetadataObjectTypeEAN13Code, AVMetadataObjectTypeEAN8Code, AVMetadataObjectTypeCode128Code]];\n?????\n????AVCaptureVideoPreviewLayer *layer = [AVCaptureVideoPreviewLayer layerWithSession:self.session];\n????layer.videoGravity = AVLayerVideoGravityResizeAspectFill;\n????layer.frame = self.view.bounds;\n?\n????[self.view.layer insertSublayer:layer atIndex:0];\n????self.scan = [[SAScan alloc] initWithFrame:self.view.bounds];\n????[self.view addSubview:self.scan];\n?????\n????NSURL *url = [NSURL URLWithString:[[NSBundle mainBundle] pathForResource:@\"scan\" ofType:@\"mp3\"]];\n????self.player = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:nil];\n?????\n????UIBarButtonItem *item = [[UIBarButtonItem alloc] initWithTitle:@\"\u91cd\u8bd5\" style:UIBarButtonItemStylePlain target:self action:@selector(startRunning)];\n????[self.navigationItem setRightBarButtonItem:item];\n}\n?\n- (void)viewWillAppear:(BOOL)animated\n{\n????[super viewWillAppear:animated];\n????[self.session startRunning];\n}\n?\n- (void)viewDidAppear:(BOOL)animated\n{\n????[super viewDidAppear:animated];\n????[self.scan startAnimation];\n}\n?\n- (void)viewWillDisappear:(BOOL)animated\n{\n????[super viewWillDisappear:animated];\n????[self.session stopRunning];\n}\n?\n- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:(NSArray *)metadataObjects fromConnection:(AVCaptureConnection *)connection\n{\n????if (metadataObjects.count > 0){\n????????AVMetadataMachineReadableCodeObject *metadataObject = [metadataObjects firstObject];\n????????[self.player play];\n????????[self.scan stopAnimation];\n????????[self.session stopRunning];\n????????if (self.block) self.block(metadataObject.stringValue);\n????????[self.navigationController popViewControllerAnimated:YES];\n????????[self dismissViewControllerAnimated:YES completion:nil];\n????}\n}\n?\n- (void)startRunning\n{\n????[self.session startRunning];\n????[self.scan startAnimation];\n}\n@end<\/pre>\n<p>Scan.m<\/p>\n<pre lang=\"objc\" line=\"1\">\/\/\n\/\/? SAScan.m\n\/\/\n\/\/\n\/\/? Created by \u4f59\u897f\u5b89 on 15\/12\/3.\n\/\/? Copyright ? 2015\u5e74 Sian. All rights reserved.\n\/\/\n?\n#import \"SAScan.h\"\n?\n@implementation SAScan\n?\n- (instancetype)initWithFrame:(CGRect)frame\n{\n????if (self = [super initWithFrame:frame]){\n????????self.backgroundColor = [UIColor clearColor];\n????????UIImage *line = [UIImage imageNamed:@\"scanLine.png\"];\n????????self.scanLine = [[UIImageView alloc] initWithImage:line];\n????????[self.scanLine setHidden:YES];\n????????[self addSubview:self.scanLine];\n????}\n????return self;\n}\n?\n- (void)drawRect:(CGRect)rect\n{\n????CGContextRef context = UIGraphicsGetCurrentContext();\n????\/\/\u975e\u626b\u7801\u533a\u57df\u534a\u900f\u660e\n????{\n????????CGFloat w = self.bounds.size.width * 0.7;\n????????CGFloat x = (self.bounds.size.width - w) * 0.5;\n????????CGFloat y = (self.bounds.size.height - w) * 0.5;\n????????{?? \/\/ \u5916\u56f4\u533a\u57df\u586b\u5145\u534a\u900f\u660e\u9ed1\u8272\n????????????\/\/ \u8bbe\u7f6e\u975e\u8bc6\u522b\u533a\u57df\u989c\u8272\n????????????CGContextSetRGBFillColor(context, 0, 0, 0, 0.6);\n?????????????\n????????????\/\/ \u626b\u7801\u533a\u57df\u4e0a\u9762\u586b\u5145\n????????????CGRect rect = CGRectMake(0, 0, self.frame.size.width, y);\n????????????CGContextFillRect(context, rect);\n?????????????\n????????????\/\/ \u626b\u7801\u533a\u57df\u5de6\u8fb9\u586b\u5145\n????????????rect = CGRectMake(0, y, x, w);\n????????????CGContextFillRect(context, rect);\n?????????????\n????????????\/\/ \u626b\u7801\u533a\u57df\u53f3\u8fb9\u586b\u5145\n????????????rect = CGRectMake(x + w, y, x, w);\n????????????CGContextFillRect(context, rect);\n?????????????\n????????????\/\/ \u626b\u7801\u533a\u57df\u4e0b\u9762\u586b\u5145\n????????????rect = CGRectMake(0, y + w, self.frame.size.width, self.frame.size.height - y - w);\n????????????CGContextFillRect(context, rect);\n????????}\n?????????\n????????{?? \/\/ \u4e2d\u95f4\u53ef\u89c6\u533a\u57df\u753b\u8fb9\u6846\n????????????UIColor *whiteColor = [UIColor colorWithWhite:1.0 alpha:0.5];\n????????????CGContextSetStrokeColorWithColor(context, whiteColor.CGColor);\n????????????CGContextSetLineWidth(context, 1);\n????????????CGContextAddRect(context, CGRectMake(x, y, w, w));\n????????????CGContextStrokePath(context);\n????????}\n?????????\n?????????\n????????{?? \/\/ \u4e2d\u95f4\u53ef\u89c6\u533a\u57df\u753b\u89d2\u6846\n????????????CGFloat lineWidth = 4.0f;\n????????????CGFloat angleWidth = 15.0f;\n????????????UIColor *greenColor = [UIColor colorWithRed:0 green:1.0 blue:0 alpha:0.8];\n????????????CGContextSetLineWidth(context, lineWidth);\n????????????CGContextSetStrokeColorWithColor(context, greenColor.CGColor);\n?????????????\n????????????\/\/ \u5de6\u4e0a\u89d2\n????????????CGContextMoveToPoint(context, x, y + angleWidth);\n????????????CGContextAddLineToPoint(context, x, y);\n????????????CGContextAddLineToPoint(context, x + angleWidth, y);\n????????????\/\/ \u53f3\u4e0a\u89d2\n????????????CGContextMoveToPoint(context, x + w - angleWidth, y);\n????????????CGContextAddLineToPoint(context, x + w, y);\n????????????CGContextAddLineToPoint(context, x + w, y + angleWidth);\n????????????\/\/ \u53f3\u4e0b\u89d2\n????????????CGContextMoveToPoint(context, x + w, y + w - angleWidth);\n????????????CGContextAddLineToPoint(context, x + w, y + w);\n????????????CGContextAddLineToPoint(context, x + w - angleWidth, y + w);\n????????????\/\/ \u5de6\u4e0b\u89d2\n????????????CGContextMoveToPoint(context, x + angleWidth, y + w);\n????????????CGContextAddLineToPoint(context, x, y + w);\n????????????CGContextAddLineToPoint(context, x, y + w - angleWidth);\n????????}\n????????CGContextStrokePath(context);\n????}\n}\n?\n- (void)layoutSubviews\n{\n????[super layoutSubviews];\n????CGFloat width = self.bounds.size.width;\n????CGFloat y = (self.bounds.size.height - width * 0.7) * 0.5;\n????self.scanLine.frame = CGRectMake(0, y, width, 12);\n}\n?\n- (void)startAnimation\n{\n????CGFloat width = self.bounds.size.width;\n????CGFloat y = (self.bounds.size.height - width * 0.7) * 0.5;\n????self.scanLine.frame = CGRectMake(0, y, width, 12);\n????self.scanLine.hidden = NO;\n????[UIView animateWithDuration:2.5 delay:0 options:UIViewAnimationOptionRepeat | UIViewAnimationOptionCurveLinear animations:^{\n????????self.scanLine.center = CGPointMake(width * 0.5, y + width * 0.7);\n????} completion:^(BOOL finished) {\n????????if (finished) self.scanLine.center = CGPointMake(width * 0.5, y);\n????}];\n}\n?\n- (void)stopAnimation\n{\n????self.scanLine.hidden = YES;\n????[self.scanLine.layer removeAllAnimations];\n}\n@end<\/pre>\n<p><strong>4\u3001\u4f7f\u7528\u53ea\u9700\u4e00\u884c\u4ee3\u7801<\/strong>\uff1a<\/p>\n<pre lang=\"objc\" line=\"1\">\n    SAScanCtrl *scan = [[SAScanCtrl alloc] initWithBlock:^(NSString *string) {\n        [[[UIAlertView alloc] initWithTitle:nil message:string delegate:nil cancelButtonTitle:@\"OK\" otherButtonTitles:nil, nil] show];\n    }];\n    UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:scan];\n    [self presentViewController:nav animated:YES completion:nil];<\/pre>\n<p><strong>5\u3001Demo\u4e0b\u8f7d<\/strong><\/p>\n<p><a href=\"http:\/\/www.yusian.com\/blog\/wp-content\/uploads\/2016\/07\/SAScan.zip\">SAScan<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>1\u3001\u5148\u4e0a\u56fe\u770b\u770b\u6548\u679c 2\u3001\u8bbe\u8ba1\u601d\u8def 2.1\u3001\u5229\u7528AVCaptureMetadataOutput\u56fa\u6709\u7684\u8f93\u51fa\u5c5e\u6027\uff0c\u80fd\u591f\u8f93\u51fa\u4e8c\u7ef4\u7801\u53ca\u6761\u5f62\u7801\u7684\u89e3\u6790\u7ed3\u679c 2.2\u3001\u5229\u7528Quartz 2D\u7ed8\u51fa\u57fa\u672c\u626b\u63cf\u754c\u9762\uff0c\u7ed3\u5408\u52a8\u753b\u6548\u679c\uff0c\u7b80\u5355\u53c8\u9ad8\u6548\uff012.3\u3001\u53ea\u9700\u4e24\u4e2a\u7c7b\uff0c\u4e00\u4e2a\u63a7\u5236\u5668\uff0c\u4e00\u4e2a\u89c6\u56fe\uff1aSAScanCtrl SAScan 2.3\u3001\u5176\u4ed6\u5185\u5bb9\u5728\u4ee3\u7801\u4e2d\u7ed9\u51fa\u76f8\u5173\u6ce8\u91ca\u8bf4\u660e<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[11],"tags":[15],"class_list":["post-176","post","type-post","status-publish","format-standard","hentry","category-project","tag-module"],"_links":{"self":[{"href":"https:\/\/www.yusian.com\/blog\/wp-json\/wp\/v2\/posts\/176","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.yusian.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.yusian.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.yusian.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.yusian.com\/blog\/wp-json\/wp\/v2\/comments?post=176"}],"version-history":[{"count":0,"href":"https:\/\/www.yusian.com\/blog\/wp-json\/wp\/v2\/posts\/176\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.yusian.com\/blog\/wp-json\/wp\/v2\/media?parent=176"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.yusian.com\/blog\/wp-json\/wp\/v2\/categories?post=176"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.yusian.com\/blog\/wp-json\/wp\/v2\/tags?post=176"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}