Commit d134b88a3685ed4356389269733402c758bd8d1c

Authored by 梁星国
1 parent cc3abe0e

提交编写测试工程

CNLiveScanGoodsCamera.podspec
@@ -30,7 +30,7 @@ TODO: Add long description of the pod here. @@ -30,7 +30,7 @@ TODO: Add long description of the pod here.
30 30
31 s.ios.deployment_target = '8.0' 31 s.ios.deployment_target = '8.0'
32 32
33 - s.source_files = 'CNLiveScanGoodsCamera/Classes/**/*' 33 + s.source_files = 'CNLiveScanGoodsCamera/Classes/*.{h,m}'
34 34
35 # s.resource_bundles = { 35 # s.resource_bundles = {
36 # 'CNLiveScanGoodsCamera' => ['CNLiveScanGoodsCamera/Assets/*.png'] 36 # 'CNLiveScanGoodsCamera' => ['CNLiveScanGoodsCamera/Assets/*.png']
@@ -38,5 +38,7 @@ TODO: Add long description of the pod here. @@ -38,5 +38,7 @@ TODO: Add long description of the pod here.
38 38
39 # s.public_header_files = 'Pod/Classes/**/*.h' 39 # s.public_header_files = 'Pod/Classes/**/*.h'
40 # s.frameworks = 'UIKit', 'MapKit' 40 # s.frameworks = 'UIKit', 'MapKit'
41 - # s.dependency 'AFNetworking', '~> 2.3' 41 + s.dependency 'AFNetworking'
  42 +# #基础请求组件库
  43 +# s.dependency 'CNLiveRequestBastKit'
42 end 44 end
CNLiveScanGoodsCamera/Classes/CNLiveCutGridLayer.h 0 → 100644
  1 +//
  2 +// CNLiveCutGridLayer.h
  3 +// CNLiveScanGoodsCamera
  4 +//
  5 +// Created by 梁星国 on 2020/5/9.
  6 +//
  7 +
  8 +#import <QuartzCore/QuartzCore.h>
  9 +
  10 +NS_ASSUME_NONNULL_BEGIN
  11 +
  12 +@interface CNLiveCutGridLayer : CALayer
  13 +
  14 +@property (nonatomic, assign) CGRect clippingRect; //裁剪范围
  15 +@property (nonatomic, strong) UIColor *bgColor; //背景颜色
  16 +@property (nonatomic, strong) UIColor *gridColor; //线条颜色
  17 +
  18 +@end
  19 +
  20 +NS_ASSUME_NONNULL_END
CNLiveScanGoodsCamera/Classes/CNLiveCutGridLayer.m 0 → 100644
  1 +//
  2 +// CNLiveCutGridLayer.m
  3 +// CNLiveScanGoodsCamera
  4 +//
  5 +// Created by 梁星国 on 2020/5/9.
  6 +//
  7 +
  8 +#import "CNLiveCutGridLayer.h"
  9 +
  10 +@implementation CNLiveCutGridLayer
  11 +
  12 +- (void)drawInContext:(CGContextRef)context {
  13 + CGRect rct = self.bounds;
  14 + CGContextSetFillColorWithColor(context, self.bgColor.CGColor);
  15 + CGContextFillRect(context, rct);
  16 +
  17 + //清除范围(截图范围)
  18 + CGContextClearRect(context, _clippingRect);
  19 +
  20 + CGContextSetStrokeColorWithColor(context, self.gridColor.CGColor);
  21 + CGContextSetLineWidth(context, 0.8);
  22 +
  23 + rct = self.clippingRect;
  24 +
  25 + CGContextBeginPath(context);
  26 + CGFloat dW = 0;
  27 + //画竖线
  28 + for(int i = 0;i < 4; ++i){
  29 + CGContextMoveToPoint(context, rct.origin.x + dW, rct.origin.y);
  30 + CGContextAddLineToPoint(context, rct.origin.x + dW, rct.origin.y + rct.size.height);
  31 + dW += _clippingRect.size.width / 3;
  32 + }
  33 + dW = 0;
  34 + //画横线
  35 + for(int i = 0;i < 4; ++i){
  36 + CGContextMoveToPoint(context, rct.origin.x, rct.origin.y + dW);
  37 + CGContextAddLineToPoint(context, rct.origin.x + rct.size.width, rct.origin.y + dW);
  38 + dW += rct.size.height/3;
  39 + }
  40 + CGContextStrokePath(context);
  41 +}
  42 +
  43 +@end
CNLiveScanGoodsCamera/Classes/CNLiveCutImageToolView.h 0 → 100644
  1 +//
  2 +// CNLiveCutImageToolView.h
  3 +// CNLiveScanGoodsCamera
  4 +//
  5 +// Created by 梁星国 on 2020/5/9.
  6 +//
  7 +
  8 +#import <UIKit/UIKit.h>
  9 +
  10 +NS_ASSUME_NONNULL_BEGIN
  11 +
  12 +@interface CNLiveCutImageToolView : UIView
  13 +
  14 +@property (nonatomic, copy) void (^cancelBlock)(void);
  15 +@property (nonatomic, copy) void (^finishBlock)(UIImage *image);
  16 +
  17 +/// selectClipRatio 0 = 全屏 1 = 1:1
  18 ++(instancetype)showViewWithImg:(UIImage *)image andSelectClipRatio:(CGFloat)selectClipRatio;
  19 +
  20 +@end
  21 +
  22 +NS_ASSUME_NONNULL_END
CNLiveScanGoodsCamera/Classes/CNLiveCutImageToolView.m 0 → 100644
  1 +//
  2 +// CNLiveCutImageToolView.m
  3 +// CNLiveScanGoodsCamera
  4 +//
  5 +// Created by 梁星国 on 2020/5/9.
  6 +//
  7 +
  8 +#import "CNLiveCutImageToolView.h"
  9 +#import "CNLiveCutGridLayer.h"
  10 +#import "CNLiveCutSquareView.h"
  11 +
  12 +static const NSUInteger kLeftTopCircleView = 0;
  13 +static const NSUInteger kLeftBottomCircleView = 1;
  14 +static const NSUInteger kRightTopCircleView = 2;
  15 +static const NSUInteger kRightBottomCircleView = 3;
  16 +
  17 +// 屏幕尺寸定义
  18 +#define KScreenBounds [UIScreen mainScreen].bounds
  19 +#define kScreenW [UIScreen mainScreen].bounds.size.width
  20 +#define kScreenH [UIScreen mainScreen].bounds.size.height
  21 +
  22 +
  23 +@interface CNLiveCutImageToolView ()
  24 +
  25 +@property (nonatomic, strong) UIImage *image;
  26 +@property (nonatomic, strong) UIImageView *imageView;
  27 +/// 裁剪范围
  28 +@property (nonatomic, assign) CGRect clippingRect;
  29 +
  30 +@property (nonatomic, assign) CGFloat selectClipRatio;
  31 +@end
  32 +
  33 +@implementation CNLiveCutImageToolView
  34 +{
  35 + CNLiveCutGridLayer *_gridLayer;
  36 + //4个角
  37 + CNLiveCutSquareView *_ltView;
  38 + CNLiveCutSquareView *_lbView;
  39 + CNLiveCutSquareView *_rtView;
  40 + CNLiveCutSquareView *_rbView;
  41 +}
  42 +
  43 +
  44 +-(instancetype)initWithFrame:(CGRect)frame withImg:(UIImage *)image andSelectClipRatio:(CGFloat)selectClipRatio
  45 +{
  46 + self = [super initWithFrame:frame];
  47 + if (self) {
  48 + self.image = image;
  49 + [self initUI];
  50 + self.selectClipRatio = selectClipRatio;
  51 + }
  52 + return self;
  53 +}
  54 +
  55 +-(void)initUI
  56 +{
  57 + self.backgroundColor = [UIColor blueColor];
  58 +
  59 + self.imageView = [[UIImageView alloc] init];
  60 + self.imageView.image = self.image;
  61 + [self addSubview:self.imageView];
  62 + [self setImageViewFrame];
  63 + /// 拖动裁剪区域
  64 + UIPanGestureRecognizer *panGesture = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(panGridView:)];
  65 + self.imageView.userInteractionEnabled = YES;
  66 + [self.imageView addGestureRecognizer:panGesture];
  67 + /// 保存
  68 + UIView *bottomView = [[UIView alloc] init];
  69 + bottomView.backgroundColor = [UIColor colorWithWhite:0.3 alpha:0.9];
  70 + [self addSubview:bottomView];
  71 +
  72 + bottomView.frame = CGRectMake(0, [UIScreen mainScreen].bounds.size.height - 87, [UIScreen mainScreen].bounds.size.width, 87);
  73 +
  74 +
  75 + UIButton *saveBtn = [UIButton buttonWithType:UIButtonTypeCustom];
  76 + [saveBtn setBackgroundColor:[UIColor yellowColor]];
  77 + saveBtn.frame = CGRectMake(0, 0, 87, 87);
  78 + [bottomView addSubview:saveBtn];
  79 + [saveBtn addTarget:self action:@selector(save) forControlEvents:UIControlEventTouchUpInside];
  80 +
  81 +// /// 关闭
  82 +// UIButton *closeBtn = [UIButton zz_buttonWithTitle:nil imageName:@"home_customCamera_close" target:self action:@selector(close)];
  83 +// [bottomView addSubview:closeBtn];
  84 +//
  85 +// [closeBtn mas_makeConstraints:^(MASConstraintMaker *make) {
  86 +// make.centerY.equalTo(saveBtn);
  87 +// make.right.equalTo(bottomView).offset(-10);
  88 +// make.width.height.equalTo(@47);
  89 +// }];
  90 +
  91 + /// 图片裁剪
  92 + _gridLayer = [[CNLiveCutGridLayer alloc] init];
  93 + _gridLayer.frame = self.imageView.bounds;
  94 + _gridLayer.bgColor = [[UIColor blackColor] colorWithAlphaComponent:.5];
  95 + _gridLayer.gridColor = [UIColor whiteColor];
  96 + [self.imageView.layer addSublayer:_gridLayer];
  97 +
  98 + _ltView = [self clippingCircleWithTag:kLeftTopCircleView];
  99 + _lbView = [self clippingCircleWithTag:kLeftBottomCircleView];
  100 + _rtView = [self clippingCircleWithTag:kRightTopCircleView];
  101 + _rbView = [self clippingCircleWithTag:kRightBottomCircleView];
  102 +}
  103 +
  104 +/// 设置 ImageViewFrame
  105 +- (void)setImageViewFrame
  106 +{
  107 + CGFloat maxH = kScreenH - 87 - 20;
  108 + CGFloat imgW = self.image.size.width;
  109 + CGFloat imgH = self.image.size.height;
  110 + CGFloat w = kScreenW - 20;
  111 + CGFloat h = w * imgH / imgW;
  112 + if (h > maxH) {
  113 + h = maxH;
  114 + w = h * imgW / imgH;
  115 + }
  116 +
  117 + CGRect frame = CGRectMake((kScreenW - w) * 0.5, (maxH - h) * 0.5 + 10, w, h);
  118 + self.imageView.frame = frame;
  119 +}
  120 +
  121 +-(void)setSelectClipRatio:(CGFloat)selectClipRatio
  122 +{
  123 + _selectClipRatio = selectClipRatio;
  124 + CGRect rect = _imageView.bounds;
  125 + if (self.selectClipRatio != 0) {
  126 + CGFloat H = rect.size.width * self.selectClipRatio;
  127 + if (H <= rect.size.height) {
  128 + rect.size.height = H;
  129 + } else {
  130 + rect.size.width *= rect.size.height / H;
  131 + }
  132 +
  133 + rect.origin.x = (_imageView.bounds.size.width - rect.size.width) / 2;
  134 + rect.origin.y = (_imageView.bounds.size.height - rect.size.height) / 2;
  135 + }
  136 + self.clippingRect = rect;
  137 +}
  138 +
  139 +// 4个角的拖动圆球
  140 +- (CNLiveCutSquareView *)clippingCircleWithTag:(NSInteger)tag
  141 +{
  142 + CNLiveCutSquareView *view = [[CNLiveCutSquareView alloc] initWithFrame:CGRectMake(0, 0, 50, 50)];
  143 + view.tag = tag;
  144 +
  145 + UIPanGestureRecognizer *panGesture = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(panCircleView:)];
  146 + [view addGestureRecognizer:panGesture];
  147 +
  148 + [self addSubview:view];
  149 +
  150 + return view;
  151 +}
  152 +
  153 +/// 设置裁剪区域
  154 +- (void)setClippingRect:(CGRect)clippingRect
  155 +{
  156 + _clippingRect = clippingRect;
  157 + _ltView.center = [self convertPoint:CGPointMake(clippingRect.origin.x, clippingRect.origin.y) fromView:_imageView];
  158 + _lbView.center = [self convertPoint:CGPointMake(clippingRect.origin.x, clippingRect.origin.y+clippingRect.size.height) fromView:_imageView];
  159 + _rtView.center = [self convertPoint:CGPointMake(clippingRect.origin.x+clippingRect.size.width, clippingRect.origin.y) fromView:_imageView];
  160 + _rbView.center = [self convertPoint:CGPointMake(clippingRect.origin.x+clippingRect.size.width, clippingRect.origin.y+clippingRect.size.height) fromView:_imageView];
  161 +
  162 + _gridLayer.clippingRect = clippingRect;
  163 + [self setNeedsDisplay];
  164 +}
  165 +
  166 +- (void)setNeedsDisplay
  167 +{
  168 + [super setNeedsDisplay];
  169 + [_gridLayer setNeedsDisplay];
  170 +}
  171 +
  172 +
  173 +#pragma mark - 拖动
  174 +// 拖动4个角
  175 +- (void)panCircleView:(UIPanGestureRecognizer*)sender
  176 +{
  177 + CGPoint point = [sender locationInView:_imageView];
  178 + CGPoint dp = [sender translationInView:_imageView];
  179 +
  180 + CGRect rct = self.clippingRect;
  181 +
  182 + const CGFloat W = _imageView.frame.size.width;
  183 + const CGFloat H = _imageView.frame.size.height;
  184 + CGFloat minX = 0;
  185 + CGFloat minY = 0;
  186 + CGFloat maxX = W;
  187 + CGFloat maxY = H;
  188 +
  189 + CGFloat ratio = (sender.view.tag == 1 || sender.view.tag == 2) ? -self.selectClipRatio : self.selectClipRatio;
  190 +
  191 + switch (sender.view.tag) {
  192 + case 0: // upper left
  193 + {
  194 + maxX = MAX((rct.origin.x + rct.size.width) - 0.1 * W, 0.1 * W);
  195 + maxY = MAX((rct.origin.y + rct.size.height) - 0.1 * H, 0.1 * H);
  196 +
  197 + if (ratio!=0) {
  198 + CGFloat y0 = rct.origin.y - ratio * rct.origin.x;
  199 + CGFloat x0 = -y0 / ratio;
  200 + minX = MAX(x0, 0);
  201 + minY = MAX(y0, 0);
  202 +
  203 + point.x = MAX(minX, MIN(point.x, maxX));
  204 + point.y = MAX(minY, MIN(point.y, maxY));
  205 +
  206 + if(-dp.x*ratio + dp.y > 0){ point.x = (point.y - y0) / ratio; }
  207 + else{ point.y = point.x * ratio + y0; }
  208 + } else {
  209 + point.x = MAX(minX, MIN(point.x, maxX));
  210 + point.y = MAX(minY, MIN(point.y, maxY));
  211 + }
  212 +
  213 + rct.size.width = rct.size.width - (point.x - rct.origin.x);
  214 + rct.size.height = rct.size.height - (point.y - rct.origin.y);
  215 + rct.origin.x = point.x;
  216 + rct.origin.y = point.y;
  217 + break;
  218 + }
  219 + case 1: // lower left
  220 + {
  221 + maxX = MAX((rct.origin.x + rct.size.width) - 0.1 * W, 0.1 * W);
  222 + minY = MAX(rct.origin.y + 0.1 * H, 0.1 * H);
  223 +
  224 + if (ratio!=0) {
  225 + CGFloat y0 = (rct.origin.y + rct.size.height) - ratio* rct.origin.x ;
  226 + CGFloat xh = (H - y0) / ratio;
  227 + minX = MAX(xh, 0);
  228 + maxY = MIN(y0, H);
  229 +
  230 + point.x = MAX(minX, MIN(point.x, maxX));
  231 + point.y = MAX(minY, MIN(point.y, maxY));
  232 +
  233 + if(-dp.x*ratio + dp.y < 0){ point.x = (point.y - y0) / ratio; }
  234 + else{ point.y = point.x * ratio + y0; }
  235 + } else {
  236 + point.x = MAX(minX, MIN(point.x, maxX));
  237 + point.y = MAX(minY, MIN(point.y, maxY));
  238 + }
  239 +
  240 + rct.size.width = rct.size.width - (point.x - rct.origin.x);
  241 + rct.size.height = point.y - rct.origin.y;
  242 + rct.origin.x = point.x;
  243 + break;
  244 + }
  245 + case 2: // upper right
  246 + {
  247 + minX = MAX(rct.origin.x + 0.1 * W, 0.1 * W);
  248 + maxY = MAX((rct.origin.y + rct.size.height) - 0.1 * H, 0.1 * H);
  249 +
  250 + if (ratio!=0) {
  251 + CGFloat y0 = rct.origin.y - ratio * (rct.origin.x + rct.size.width);
  252 + CGFloat yw = ratio * W + y0;
  253 + CGFloat x0 = -y0 / ratio;
  254 + maxX = MIN(x0, W);
  255 + minY = MAX(yw, 0);
  256 +
  257 + point.x = MAX(minX, MIN(point.x, maxX));
  258 + point.y = MAX(minY, MIN(point.y, maxY));
  259 +
  260 + if(-dp.x*ratio + dp.y > 0){ point.x = (point.y - y0) / ratio; }
  261 + else{ point.y = point.x * ratio + y0; }
  262 + } else {
  263 + point.x = MAX(minX, MIN(point.x, maxX));
  264 + point.y = MAX(minY, MIN(point.y, maxY));
  265 + }
  266 +
  267 + rct.size.width = point.x - rct.origin.x;
  268 + rct.size.height = rct.size.height - (point.y - rct.origin.y);
  269 + rct.origin.y = point.y;
  270 + break;
  271 + }
  272 + case 3: // lower right
  273 + {
  274 + minX = MAX(rct.origin.x + 0.1 * W, 0.1 * W);
  275 + minY = MAX(rct.origin.y + 0.1 * H, 0.1 * H);
  276 +
  277 + if (ratio!=0) {
  278 + CGFloat y0 = (rct.origin.y + rct.size.height) - ratio * (rct.origin.x + rct.size.width);
  279 + CGFloat yw = ratio * W + y0;
  280 + CGFloat xh = (H - y0) / ratio;
  281 + maxX = MIN(xh, W);
  282 + maxY = MIN(yw, H);
  283 +
  284 + point.x = MAX(minX, MIN(point.x, maxX));
  285 + point.y = MAX(minY, MIN(point.y, maxY));
  286 +
  287 + if(-dp.x*ratio + dp.y < 0){ point.x = (point.y - y0) / ratio; }
  288 + else{ point.y = point.x * ratio + y0; }
  289 + } else {
  290 + point.x = MAX(minX, MIN(point.x, maxX));
  291 + point.y = MAX(minY, MIN(point.y, maxY));
  292 + }
  293 +
  294 + rct.size.width = point.x - rct.origin.x;
  295 + rct.size.height = point.y - rct.origin.y;
  296 + break;
  297 + }
  298 + default:
  299 + break;
  300 + }
  301 + self.clippingRect = rct;
  302 +}
  303 +
  304 +//移动裁剪view
  305 +- (void)panGridView:(UIPanGestureRecognizer*)sender
  306 +{
  307 + static BOOL dragging = NO;
  308 + static CGRect initialRect;
  309 +
  310 + if (sender.state==UIGestureRecognizerStateBegan) {
  311 + CGPoint point = [sender locationInView:_imageView];
  312 + dragging = CGRectContainsPoint(_clippingRect, point);
  313 + initialRect = self.clippingRect;
  314 + } else if(dragging) {
  315 + CGPoint point = [sender translationInView:_imageView];
  316 + CGFloat left = MIN(MAX(initialRect.origin.x + point.x, 0), _imageView.frame.size.width-initialRect.size.width);
  317 + CGFloat top = MIN(MAX(initialRect.origin.y + point.y, 0), _imageView.frame.size.height-initialRect.size.height);
  318 +
  319 + CGRect rct = self.clippingRect;
  320 + rct.origin.x = left;
  321 + rct.origin.y = top;
  322 + self.clippingRect = rct;
  323 + }
  324 +}
  325 +
  326 +
  327 +/// 裁剪
  328 +-(void)executeCutCompletion
  329 +{
  330 + CGFloat zoomScale = self.imageView.frame.size.width / self.imageView.image.size.width;
  331 + CGRect rct = _gridLayer.clippingRect;
  332 + rct.size.width /= zoomScale;
  333 + rct.size.height /= zoomScale;
  334 + rct.origin.x /= zoomScale;
  335 + rct.origin.y /= zoomScale;
  336 + CGPoint origin = CGPointMake(-rct.origin.x, -rct.origin.y);
  337 + UIGraphicsBeginImageContextWithOptions(rct.size, NO, self.imageView.image.scale);
  338 + [self.imageView.image drawAtPoint:origin];
  339 + UIImage *img = UIGraphicsGetImageFromCurrentImageContext();
  340 + UIGraphicsEndImageContext();
  341 + !self.finishBlock ? : self.finishBlock(img);
  342 +}
  343 +
  344 +/// 保存
  345 +-(void)save
  346 +{
  347 + [self executeCutCompletion];
  348 + [self removeFromSuperview];
  349 +}
  350 +
  351 +/// 关闭
  352 +-(void)close
  353 +{
  354 + !self.cancelBlock ? : self.cancelBlock();
  355 + [self removeFromSuperview];
  356 +}
  357 +
  358 ++(instancetype)showViewWithImg:(UIImage *)image andSelectClipRatio:(CGFloat)selectClipRatio
  359 +{
  360 + UIView *keyWindow = [UIApplication sharedApplication].keyWindow;
  361 +
  362 + CNLiveCutImageToolView *view = [[CNLiveCutImageToolView alloc] initWithFrame:keyWindow.bounds withImg:image andSelectClipRatio:selectClipRatio];
  363 + [keyWindow addSubview:view];
  364 +
  365 + return view;
  366 +}
  367 +
  368 +@end
CNLiveScanGoodsCamera/Classes/CNLiveCutSquareView.h 0 → 100644
  1 +//
  2 +// CNLiveCutSquareView.h
  3 +// CNLiveScanGoodsCamera
  4 +//
  5 +// Created by 梁星国 on 2020/5/9.
  6 +//
  7 +
  8 +#import <UIKit/UIKit.h>
  9 +
  10 +NS_ASSUME_NONNULL_BEGIN
  11 +
  12 +@interface CNLiveCutSquareView : UIView
  13 +
  14 +@end
  15 +
  16 +NS_ASSUME_NONNULL_END
CNLiveScanGoodsCamera/Classes/CNLiveCutSquareView.m 0 → 100644
  1 +//
  2 +// CNLiveCutSquareView.m
  3 +// CNLiveScanGoodsCamera
  4 +//
  5 +// Created by 梁星国 on 2020/5/9.
  6 +//
  7 +
  8 +#import "CNLiveCutSquareView.h"
  9 +
  10 +@implementation CNLiveCutSquareView
  11 +
  12 +- (id)initWithFrame:(CGRect)frame
  13 +{
  14 + self = [super initWithFrame:frame];
  15 + if (self) {
  16 + self.backgroundColor = [UIColor clearColor];
  17 + }
  18 + return self;
  19 +}
  20 +
  21 +- (void)drawRect:(CGRect)rect
  22 +{
  23 + CGContextRef context = UIGraphicsGetCurrentContext();
  24 +
  25 + CGRect rct = self.bounds;
  26 + rct.origin.x = rct.size.width / 2 - rct.size.width / 6;
  27 + rct.origin.y = rct.size.height / 2 - rct.size.height / 6;
  28 + rct.size.width /= 3;
  29 + rct.size.height /= 3;
  30 +
  31 + CGContextSetFillColorWithColor(context, [UIColor yellowColor].CGColor);
  32 + CGContextFillEllipseInRect(context, rct);
  33 +}
  34 +
  35 +@end
CNLiveScanGoodsCamera/Classes/CNLiveScanGoodsCameraControlView.h 0 → 100644
  1 +//
  2 +// CNLiveScanGoodsCameraControlView.h
  3 +// CNLiveScanGoodsCamera
  4 +//
  5 +// Created by 梁星国 on 2020/5/9.
  6 +//
  7 +
  8 +#import <UIKit/UIKit.h>
  9 +
  10 +@class CNLiveScanGoodsCameraControlView;
  11 +
  12 +
  13 +NS_ASSUME_NONNULL_BEGIN
  14 +
  15 +typedef void(^ClickTakePhotoBlock)(CNLiveScanGoodsCameraControlView * controlView,UIButton * takePhotoBtn);
  16 +
  17 +@interface CNLiveScanGoodsCameraControlView : UIView
  18 +
  19 +@property (nonatomic, copy) ClickTakePhotoBlock clickTakePhotoBlock;
  20 +
  21 +@end
  22 +
  23 +NS_ASSUME_NONNULL_END
CNLiveScanGoodsCamera/Classes/CNLiveScanGoodsCameraControlView.m 0 → 100644
  1 +//
  2 +// CNLiveScanGoodsCameraControlView.m
  3 +// CNLiveScanGoodsCamera
  4 +//
  5 +// Created by 梁星国 on 2020/5/9.
  6 +//
  7 +
  8 +#import "CNLiveScanGoodsCameraControlView.h"
  9 +
  10 +@interface CNLiveScanGoodsCameraControlView ()
  11 +/// 拍照
  12 +@property (nonatomic, strong) UIButton *takePhotoBtn;
  13 +///// 相册
  14 +//@property (nonatomic, strong) UIButton *photoBtn;
  15 +///// 关闭
  16 +//@property (nonatomic, strong) UIButton *closeBtn;
  17 +
  18 +
  19 +@end
  20 +
  21 +
  22 +@implementation CNLiveScanGoodsCameraControlView
  23 +
  24 +- (instancetype)initWithFrame:(CGRect)frame
  25 +{
  26 + self = [super initWithFrame:frame];
  27 + if (self) {
  28 +
  29 + [self setupUI];
  30 + }
  31 + return self;
  32 +}
  33 +
  34 +#pragma mark - setupUI
  35 +- (void)setupUI {
  36 + [self addSubview:self.takePhotoBtn];
  37 + self.takePhotoBtn.frame = CGRectMake(100, 300, 100, 100);
  38 + [self.takePhotoBtn setBackgroundColor:[UIColor yellowColor]];
  39 +}
  40 +
  41 +#pragma mark - 实现
  42 +- (void)takePhotoAction:(UIButton *)btn {
  43 +
  44 + if (self.clickTakePhotoBlock) {
  45 + self.clickTakePhotoBlock(self, btn);
  46 + }
  47 +
  48 +}
  49 +
  50 +
  51 +#pragma mark - 懒加载
  52 +- (UIButton *)takePhotoBtn {
  53 +
  54 + if (!_takePhotoBtn) {
  55 + _takePhotoBtn = [UIButton buttonWithType:UIButtonTypeCustom];
  56 + [_takePhotoBtn addTarget:self action:@selector(takePhotoAction:) forControlEvents:UIControlEventTouchUpInside];
  57 +
  58 + }
  59 + return _takePhotoBtn;
  60 +
  61 +}
  62 +
  63 +@end
CNLiveScanGoodsCamera/Classes/CNLiveScanGoodsCameraController.h 0 → 100644
  1 +//
  2 +// CNLiveScanGoodsCameraController.h
  3 +// CNLiveScanGoodsCamera
  4 +//
  5 +// Created by 梁星国 on 2020/5/8.
  6 +//
  7 +
  8 +#import <UIKit/UIKit.h>
  9 +
  10 +NS_ASSUME_NONNULL_BEGIN
  11 +
  12 +@interface CNLiveScanGoodsCameraController : UIViewController
  13 +
  14 +@end
  15 +
  16 +NS_ASSUME_NONNULL_END
CNLiveScanGoodsCamera/Classes/CNLiveScanGoodsCameraController.m 0 → 100644
  1 +//
  2 +// CNLiveScanGoodsCameraController.m
  3 +// CNLiveScanGoodsCamera
  4 +//
  5 +// Created by 梁星国 on 2020/5/8.
  6 +//
  7 +
  8 +#import "CNLiveScanGoodsCameraController.h"
  9 +#import <AVFoundation/AVFoundation.h>
  10 +#import "CNLiveScanGoodsCameraControlView.h"
  11 +#import "CNLiveCutImageToolView.h"
  12 +#import <AFNetworking/AFNetworking.h>
  13 +
  14 +#define RESOLUTION_ARRAY [NSMutableArray arrayWithObjects:/*@"3840*2160",*/ @"1920*1080", @"1280*720", /*@"960*540", */@"640*480", @"352*288", /*@"320x240",*/ nil]
  15 +
  16 +@interface CNLiveScanGoodsCameraController () <AVCaptureAudioDataOutputSampleBufferDelegate, AVCaptureVideoDataOutputSampleBufferDelegate>{
  17 + int mWidth;
  18 + int mHeight;
  19 + int mFps;
  20 + BOOL mFrontCamera;
  21 + BOOL mStarted;
  22 +
  23 + NSDictionary *mOptions;
  24 + CIContext *mContext;
  25 +
  26 + /* picture */
  27 + BOOL mGetPicture;
  28 + UIImage *mCurrentImage;
  29 +}
  30 +
  31 +/// 捕获设备,通常是前置摄像头,后置摄像头,麦克风(音频输入)
  32 +@property (nonatomic, strong) AVCaptureDevice *device;
  33 +/// session:由他把输入输出结合在一起,并开始启动捕获设备(摄像头)
  34 +@property (nonatomic, strong) AVCaptureSession *session;
  35 +
  36 +/// AVCaptureDeviceInput 代表输入设备,他使用AVCaptureDevice 来初始化
  37 +@property (nonatomic, strong) AVCaptureDeviceInput *input;
  38 +/// 照片输出流
  39 +@property (nonatomic ,strong) AVCaptureStillImageOutput *imageOutput;
  40 +/// 图像预览层,实时显示捕获的图像
  41 +@property (nonatomic ,strong) AVCaptureVideoPreviewLayer *previewLayer;
  42 +
  43 +
  44 +/// 闪光灯
  45 +@property (nonatomic, assign) BOOL isflashOn;
  46 +/// 聚焦
  47 +@property (nonatomic, strong) UIView *focusView;
  48 +/// 拍照控制
  49 +@property (nonatomic, strong) CNLiveScanGoodsCameraControlView *controlView;
  50 +/// 放大系数
  51 +@property (nonatomic, assign) CGFloat initialPinchZoom;
  52 +
  53 +
  54 +
  55 +/// 预览图片内容
  56 +@property (nonatomic, strong) UIImageView *imageView;
  57 +/// 拍照的照片
  58 +@property (nonatomic, strong) UIImage *takedImage;
  59 +
  60 +
  61 +@end
  62 +
  63 +@implementation CNLiveScanGoodsCameraController
  64 +
  65 +- (void)dealloc
  66 +{
  67 + if ([self.session isRunning]) {
  68 + [self stopVideoCapture];
  69 + }
  70 + self.session = nil;
  71 + self->mOptions = nil;
  72 + self->mContext = nil;
  73 + [[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationDidEnterBackgroundNotification object:[UIApplication sharedApplication]];
  74 + [[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationWillEnterForegroundNotification object:[UIApplication sharedApplication]];
  75 +}
  76 +
  77 +- (void)viewDidLoad {
  78 + [super viewDidLoad];
  79 +
  80 + [self initContent];
  81 + [self startVideoCapture];
  82 + [self initUI];
  83 +
  84 +
  85 +
  86 +}
  87 +
  88 +- (BOOL)prefersStatusBarHidden
  89 +{
  90 + return true;
  91 +}
  92 +
  93 +-(void)viewWillAppear:(BOOL)animated
  94 +{
  95 + [super viewWillAppear:animated];
  96 + [self setNeedsStatusBarAppearanceUpdate];
  97 +}
  98 +
  99 +
  100 +#pragma mark - 初始化
  101 +/// 初始化
  102 +- (void)initContent {
  103 + self->mWidth = 640;
  104 + self->mHeight = 480;
  105 + self->mFps = 30;
  106 + self->mFrontCamera = NO;
  107 + self->mStarted = NO;
  108 + self->mGetPicture = NO;
  109 + self->mCurrentImage = nil;
  110 +
  111 + self->mOptions = @{ kCIContextWorkingColorSpace : [NSNull null], kCIContextOutputColorSpace : [NSNull null] };
  112 + self->mContext = [CIContext contextWithEAGLContext:[[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2] options:self->mOptions];
  113 +
  114 + [[NSNotificationCenter defaultCenter] addObserver:self
  115 + selector:@selector(applicationDidEnterBackground)
  116 + name:UIApplicationDidEnterBackgroundNotification
  117 + object:[UIApplication sharedApplication]];
  118 + [[NSNotificationCenter defaultCenter] addObserver:self
  119 + selector:@selector(applicationWillEnterForeground)
  120 + name:UIApplicationWillEnterForegroundNotification
  121 + object:[UIApplication sharedApplication]];
  122 +
  123 +}
  124 +
  125 +/// 初始化UI
  126 +-(void)initUI
  127 +{
  128 + /// 焦点视图
  129 + self.focusView = [[UIView alloc]initWithFrame:CGRectMake(0, 0, 80, 80)];
  130 + self.focusView.layer.borderWidth = 1.0;
  131 + self.focusView.layer.borderColor = [UIColor greenColor].CGColor;
  132 + [self.view addSubview:self.focusView];
  133 + self.focusView.hidden = YES;
  134 +
  135 + self.controlView = [[CNLiveScanGoodsCameraControlView alloc] initWithFrame:CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.width)];
  136 + __weak typeof(self) weakSelf = self;
  137 + /// 拍照
  138 + self.controlView.clickTakePhotoBlock = ^(CNLiveScanGoodsCameraControlView * _Nonnull controlView, UIButton * _Nonnull takePhotoBtn) {
  139 + [weakSelf onTakePicture];
  140 + };
  141 +
  142 + // /// 相册
  143 + // self.contentView.openPhotoBlock = ^{
  144 + // [weakSelf openPhotoLibrary];
  145 + // };
  146 + // /// 关闭
  147 + // self.contentView.closeBlock = ^{
  148 + // [weakSelf dismissViewControllerAnimated:true completion:nil];
  149 + // };
  150 + // /// 跳过
  151 + // self.contentView.skipBlock = ^{
  152 + // NSLog(@"跳过");
  153 + // };
  154 +
  155 + [self.view addSubview:self.controlView];
  156 +
  157 + ///捏合手势
  158 + UIPinchGestureRecognizer *pinch = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:@selector(pinchDetected:)];
  159 + [self.view addGestureRecognizer:pinch];
  160 + /// 点击手势_对焦
  161 + UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(focusGesture:)];
  162 + [self.view addGestureRecognizer:tapGesture];
  163 +}
  164 +
  165 +
  166 +#pragma mark - 私有方法
  167 +
  168 +#pragma mark -
  169 +#pragma mark - 开始拍摄
  170 +- (void) startVideoCapture {
  171 + [[UIApplication sharedApplication] setIdleTimerDisabled:YES];/*Open anti-lock*/
  172 + /*if open , set nil;*/
  173 + if (self.device || self.session) {
  174 + self.device = nil;
  175 + self.session = nil;
  176 + }
  177 +
  178 + if ((self.device = [self getAVCaptureDeviceCamera]) == nil) {
  179 + /*If the open fails, the return;*/
  180 + return;
  181 + }
  182 + /*set frame rate*/
  183 + NSError *error = nil;
  184 + if ([self.device lockForConfiguration:&error]) {
  185 + [self.device setActiveVideoMaxFrameDuration:CMTimeMake(1, self->mFps)];
  186 + [self.device setActiveVideoMinFrameDuration:CMTimeMake(1, self->mFps)];
  187 + [self.device unlockForConfiguration];
  188 + } else {
  189 + NSLog(@"videoDevice lockForConfiguration returned error %@", error);
  190 + }
  191 + /*init device input*/
  192 + error = nil;
  193 + AVCaptureDeviceInput *videoInput = [AVCaptureDeviceInput deviceInputWithDevice:self.device error:&error];
  194 + self.input = videoInput;
  195 + if (!videoInput) {
  196 + self.device = nil;
  197 + return;
  198 + }
  199 +
  200 + /// 照片输出流
  201 + AVCaptureStillImageOutput *imageOutput = [[AVCaptureStillImageOutput alloc]init];
  202 + self.imageOutput = imageOutput;
  203 +
  204 + /*init capture session*/
  205 + self.session = [[AVCaptureSession alloc] init];
  206 + if ([self.session canAddOutput:imageOutput]) {
  207 + [self.session addOutput:imageOutput];
  208 + }
  209 + if ([self.session canAddInput:videoInput]) {
  210 + [self.session addInput:videoInput];
  211 + }
  212 + /*set resolution*/
  213 + NSString *captureQuality = [NSString stringWithString:[self getCaptureQuality]];
  214 + /*begin configuration for the AVCaptureSession*/
  215 + [self.session beginConfiguration];
  216 + /*quality*/
  217 + [self.session setSessionPreset:captureQuality];
  218 +
  219 + /* Currently, the only supported key is kCVPixelBufferPixelFormatTypeKey. Recommended pixel format choices are
  220 + kCVPixelFormatType_420YpCbCr8BiPlanarFullRange(420f:YUV type) or kCVPixelFormatType_32BGRA(32 byte BGRA)...
  221 + On iPhone 3G, the recommended pixel format choices are kCVPixelFormatType_422YpCbCr8 or kCVPixelFormatType_32BGRA.
  222 + */
  223 + AVCaptureVideoDataOutput *avCaptureVideoDataOutput = [[AVCaptureVideoDataOutput alloc] init];
  224 + NSString *key = (NSString *)kCVPixelBufferPixelFormatTypeKey;//only supported key;
  225 + NSNumber *val = [NSNumber numberWithUnsignedInt:kCVPixelFormatType_420YpCbCr8BiPlanarFullRange];//h264 used YUV;
  226 + NSDictionary *settings = [NSDictionary dictionaryWithObject:val forKey:key];
  227 + avCaptureVideoDataOutput.videoSettings = settings;
  228 +
  229 + /*we create a serial queue to handle the processing of our frames*/
  230 + dispatch_queue_t queue = dispatch_queue_create("com.QuinnQiu.class.video2", NULL);
  231 + [avCaptureVideoDataOutput setSampleBufferDelegate:self queue:queue];
  232 +
  233 + /* default orientation portrait*/
  234 + [[avCaptureVideoDataOutput connectionWithMediaType:AVMediaTypeVideo] setVideoOrientation:AVCaptureVideoOrientationPortrait];
  235 + [self.session addOutput:avCaptureVideoDataOutput];
  236 + /* preview */
  237 + AVCaptureVideoPreviewLayer *previewLayer = [AVCaptureVideoPreviewLayer layerWithSession:self.session];
  238 + previewLayer.frame = CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height);
  239 + previewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill;
  240 + [self.view.layer addSublayer:previewLayer];
  241 + self.previewLayer = previewLayer;
  242 +
  243 + /* start */
  244 + self->mStarted = YES;
  245 + /* commit configuration */
  246 + [self.session commitConfiguration];
  247 + [self.session startRunning];
  248 +}
  249 +
  250 +#pragma mark - 关闭拍摄
  251 +- (void) stopVideoCapture {
  252 + [[UIApplication sharedApplication] setIdleTimerDisabled:NO];
  253 +
  254 + if ([self.session isRunning]) {
  255 + [self.session stopRunning];
  256 + }
  257 + self.session = nil;
  258 + self.device = nil;
  259 + self->mStarted = NO;
  260 +
  261 +}
  262 +
  263 +#pragma mark Get the camera device
  264 +- (AVCaptureDevice *)getAVCaptureDeviceCamera{
  265 + return [self cameraAtPosition:mFrontCamera ? AVCaptureDevicePositionFront : AVCaptureDevicePositionBack];
  266 +}
  267 +
  268 +#pragma mark - get the current camera device
  269 +- (AVCaptureDevice *)cameraAtPosition:(AVCaptureDevicePosition)position{
  270 + NSArray *cameras = [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo];//set type with AVMediaTypeVideo
  271 + for (AVCaptureDevice *device in cameras){
  272 + if (device.position == position){
  273 + return device;
  274 + }
  275 + }
  276 + return [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
  277 +}
  278 +
  279 +#pragma get capture resulotion string
  280 +-(NSString *) getCaptureQuality{
  281 + NSString *captureQuality = AVCaptureSessionPreset640x480;
  282 + switch (self->mWidth) {
  283 + case 352:
  284 + captureQuality = AVCaptureSessionPreset352x288;
  285 + break;
  286 + case 640:
  287 + captureQuality = AVCaptureSessionPreset640x480;
  288 + break;
  289 + case 960:
  290 + captureQuality = AVCaptureSessionPresetiFrame960x540;
  291 + break;
  292 + case 1280:
  293 + captureQuality = AVCaptureSessionPreset1280x720;
  294 + break;
  295 + case 1920:
  296 + captureQuality = AVCaptureSessionPreset1920x1080;
  297 + break;
  298 + case 3840:
  299 + if (@available(iOS 9.0, *)) {
  300 + captureQuality = AVCaptureSessionPreset3840x2160;
  301 + } else {
  302 + // Fallback on earlier versions
  303 + }
  304 + break;
  305 + default:
  306 + break;
  307 + }
  308 + return captureQuality;
  309 +}
  310 +
  311 +#pragma mark determint whether the current camera front camera
  312 +- (BOOL) determineTheCurrentCameraIsFront {
  313 + return mFrontCamera;
  314 +}
  315 +
  316 +#pragma mark set the front camera
  317 +- (BOOL) setFrontCamera {
  318 + if (self->mFrontCamera) {
  319 + return YES;
  320 + }
  321 +
  322 + [self stopVideoCapture];
  323 + self->mFrontCamera = YES;
  324 + [self startVideoCapture];
  325 + return YES;
  326 +}
  327 +
  328 +#pragma mark set the back camera
  329 +- (BOOL) setBackCamera {
  330 + if (!self->mFrontCamera) {
  331 + return YES;
  332 + }
  333 +
  334 + [self stopVideoCapture];
  335 + mFrontCamera = NO;
  336 + [self startVideoCapture];
  337 + return YES;
  338 +}
  339 +
  340 +#pragma mark set capture resolution
  341 +- (void) setPrepareVideoCaptureResolution: (int)width andHeight: (int)height {
  342 + self->mWidth = width;
  343 + self->mHeight = height;
  344 + /*If you are running must be stopped*/
  345 + if ([self.session isRunning]) {
  346 + [self stopVideoCapture];
  347 + [self startVideoCapture];
  348 + } else {
  349 + [self startVideoCapture];
  350 + }
  351 + mStarted = NO;
  352 +}
  353 +
  354 +#pragma mark - get resolution array of the current camera
  355 +- (NSMutableArray *) getCurrentCameraResolutionArray {
  356 + NSMutableArray *resoluArray = nil;
  357 + if (self.session) {
  358 + NSMutableArray *array = [[NSMutableArray alloc] initWithObjects:AVCaptureSessionPreset1920x1080, AVCaptureSessionPreset1280x720, AVCaptureSessionPreset640x480, AVCaptureSessionPreset352x288, nil];
  359 + resoluArray = [[NSMutableArray alloc] initWithCapacity:1];
  360 +
  361 + for (int i = 0; i < array.count; i++) {
  362 + if ([self.session canSetSessionPreset:[array objectAtIndex:i]]) {
  363 + [resoluArray addObject:[RESOLUTION_ARRAY objectAtIndex:i]];
  364 + }
  365 + }
  366 +
  367 + } else {
  368 + resoluArray = [[NSMutableArray alloc] initWithObjects:AVCaptureSessionPreset640x480, nil];
  369 + }
  370 +
  371 + return resoluArray;
  372 +}
  373 +
  374 +
  375 +#pragma mark - 通知
  376 +#pragma mark Enter background
  377 +- (void)applicationDidEnterBackground{
  378 + [self stopVideoCapture];
  379 +}
  380 +
  381 +#pragma mark enter foreground
  382 +- (void)applicationWillEnterForeground{
  383 + [self startVideoCapture];
  384 +}
  385 +
  386 +
  387 +#pragma mark rotate picture
  388 +- (UIImage *)fixOrientation:(UIImage *)image {
  389 + long double rotate = 0.0;
  390 + CGRect rect;
  391 + float translateX = 0;
  392 + float translateY = 0;
  393 + float scaleX = 1.0;
  394 + float scaleY = 1.0;
  395 +
  396 + CGSize newSize;
  397 +
  398 + if (image.size.width < image.size.height) {
  399 + newSize.width = image.size.width;
  400 + newSize.height = image.size.width / 4 * 3;//this attention;4:3
  401 + }else{
  402 + newSize = image.size;
  403 + }
  404 + /* current device orientation */
  405 + UIDeviceOrientation deviceOrientation = [[UIDevice currentDevice] orientation];
  406 + if (self->mFrontCamera) {
  407 + switch (deviceOrientation) {
  408 + case UIDeviceOrientationLandscapeRight:
  409 + rotate = 0;
  410 + rect = CGRectMake(0, 0, newSize.width, newSize.height);
  411 + translateX = 0;
  412 + translateY = 0;
  413 + break;
  414 + case UIDeviceOrientationPortraitUpsideDown:
  415 + rotate = M_PI_2;
  416 + rect = CGRectMake(0, 0, newSize.width, newSize.height);
  417 + translateX = 0;
  418 + translateY = -rect.size.width;
  419 + scaleY = rect.size.width/rect.size.height;
  420 + scaleX = rect.size.height/rect.size.width;
  421 + break;
  422 + case UIDeviceOrientationLandscapeLeft:
  423 + rotate = M_PI;
  424 + rect = CGRectMake(0, 0, newSize.width, newSize.height);
  425 + translateX = -rect.size.width;
  426 + translateY = -rect.size.height;
  427 + break;
  428 + default:
  429 + rotate = -M_PI_2;
  430 + rect = CGRectMake(0, 0, newSize.width, newSize.height);
  431 + translateX = -rect.size.height;
  432 + translateY = 0;
  433 + scaleY = rect.size.width/rect.size.height;
  434 + scaleX = rect.size.height/rect.size.width;
  435 + break;
  436 + }
  437 + }else{
  438 + switch (deviceOrientation) {
  439 + case UIDeviceOrientationLandscapeRight:
  440 + rotate = M_PI;
  441 + rect = CGRectMake(0, 0, newSize.width, newSize.height);
  442 + translateX = -rect.size.width;
  443 + translateY = -rect.size.height;
  444 + break;
  445 + case UIDeviceOrientationPortraitUpsideDown:
  446 + rotate = M_PI_2;
  447 + rect = CGRectMake(0, 0, newSize.width, newSize.height);
  448 + translateX = 0;
  449 + translateY = -rect.size.width;
  450 + scaleY = rect.size.width/rect.size.height;
  451 + scaleX = rect.size.height/rect.size.width;
  452 + break;
  453 + case UIDeviceOrientationLandscapeLeft:
  454 + rotate = 0;
  455 + rect = CGRectMake(0, 0, newSize.width, newSize.height);
  456 + translateX = 0;
  457 + translateY = 0;
  458 + break;
  459 + default:
  460 + rotate = -M_PI_2;
  461 + rect = CGRectMake(0, 0, newSize.width, newSize.height);
  462 + translateX = -rect.size.height;
  463 + translateY = 0;
  464 + scaleY = rect.size.width/rect.size.height;
  465 + scaleX = rect.size.height/rect.size.width;
  466 + break;
  467 + }
  468 + }
  469 +
  470 + UIGraphicsBeginImageContext(rect.size);
  471 + CGContextRef context = UIGraphicsGetCurrentContext();
  472 + /* Do CTM conversion */
  473 + CGContextTranslateCTM(context, 0.0, rect.size.height);
  474 + CGContextScaleCTM(context, 1.0, -1.0);
  475 + CGContextRotateCTM(context, rotate);
  476 + CGContextTranslateCTM(context, translateX, translateY);
  477 +
  478 + CGContextScaleCTM(context, scaleX, scaleY);
  479 + /* draw image */
  480 + CGContextDrawImage(context, CGRectMake(0, 0, rect.size.width, rect.size.height), image.CGImage);
  481 +
  482 + UIImage *newPic = UIGraphicsGetImageFromCurrentImageContext();
  483 + UIGraphicsEndImageContext();
  484 + return newPic;
  485 +}
  486 +
  487 +
  488 +
  489 +#pragma mark -
  490 +#pragma mark - 功能
  491 +
  492 +- (void)captureOutput:(AVCaptureFileOutput *)output
  493 +didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer
  494 + fromConnection:(AVCaptureConnection *)connection {
  495 +
  496 + if (self->mGetPicture) {
  497 + return;
  498 + }else {
  499 + self->mGetPicture = YES;
  500 + }
  501 +
  502 + /* Here only handles video stream, audio stream based on connection to distinguish */
  503 + /* Since 32BGRA very simple, here only deal with YUV format */
  504 + const int kFlags = 0;
  505 + CVImageBufferRef videoFrame = CMSampleBufferGetImageBuffer(sampleBuffer);
  506 +
  507 + if (CVPixelBufferLockBaseAddress(videoFrame, kFlags) != kCVReturnSuccess) {
  508 + return;
  509 + }
  510 +
  511 +// const int kYPlaneIndex = 0;
  512 +// const int kUVPlaneIndex = 1;
  513 +
  514 +// uint8_t *baseAddress = (uint8_t*)CVPixelBufferGetBaseAddressOfPlane(videoFrame, kYPlaneIndex);
  515 +// size_t yPlaneBytesPerRow = CVPixelBufferGetBytesPerRowOfPlane(videoFrame, kYPlaneIndex);
  516 +// size_t yPlaneHeight = CVPixelBufferGetHeightOfPlane(videoFrame, kYPlaneIndex);
  517 +// size_t uvPlaneBytesPerRow = CVPixelBufferGetBytesPerRowOfPlane(videoFrame, kUVPlaneIndex);
  518 +// size_t uvPlaneHeight = CVPixelBufferGetHeightOfPlane(videoFrame, kUVPlaneIndex);
  519 +// size_t frameSize = yPlaneBytesPerRow * yPlaneHeight + uvPlaneBytesPerRow * uvPlaneHeight;
  520 +
  521 + CVPixelBufferUnlockBaseAddress(videoFrame, kFlags);
  522 +
  523 + /* get picture */
  524 + UIImage *image = [self getCurrentImageWith:sampleBuffer];
  525 + if (!image) {
  526 + self->mGetPicture = NO;
  527 + return;
  528 + }
  529 + self->mCurrentImage = [self fixOrientation:image];
  530 +
  531 + dispatch_async(dispatch_get_global_queue(0, 0), ^{
  532 + dispatch_async(dispatch_get_main_queue(), ^{
  533 +
  534 + [self.view addSubview:self.imageView];
  535 + self.imageView.image = self->mCurrentImage;
  536 +
  537 + [self requestWithImage:self.imageView.image type:@"1"];
  538 +
  539 + });
  540 + });
  541 +
  542 +
  543 +
  544 +
  545 +}
  546 +
  547 +#pragma mark get iamge with CMSampleBufferRef
  548 +- (UIImage *) getCurrentImageWith: (CMSampleBufferRef)sampleBuffer {
  549 +
  550 + CVPixelBufferRef buffer = CMSampleBufferGetImageBuffer(sampleBuffer);
  551 + CIImage *ciImage = [CIImage imageWithCVPixelBuffer:buffer];
  552 +
  553 + CGImageRef cgImage = [mContext createCGImage:ciImage fromRect:CGRectMake(0, 0, CVPixelBufferGetWidth(buffer), CVPixelBufferGetHeight(buffer))];
  554 +
  555 + UIImage *image = [UIImage imageWithCGImage:cgImage];
  556 +
  557 + CGImageRelease(cgImage);
  558 + return image;
  559 +}
  560 +
  561 +
  562 +#pragma mark - 拖拽放大
  563 +- (void)pinchDetected:(UIPinchGestureRecognizer*)recogniser
  564 +{
  565 + if (recogniser.state == UIGestureRecognizerStateBegan)
  566 + {
  567 + _initialPinchZoom = self.device.videoZoomFactor;
  568 + }
  569 +
  570 + NSError *error = nil;
  571 + [self.device lockForConfiguration:&error];
  572 +
  573 + if (!error) {
  574 + CGFloat zoomFactor;
  575 + CGFloat scale = recogniser.scale;
  576 + if (scale < 1.0f) {
  577 + zoomFactor = _initialPinchZoom - pow(self.device.activeFormat.videoMaxZoomFactor, 1.0f - recogniser.scale);
  578 + } else {
  579 + zoomFactor = _initialPinchZoom + pow(self.device.activeFormat.videoMaxZoomFactor, (recogniser.scale - 1.0f) / 2.0f);
  580 + }
  581 +
  582 + zoomFactor = MIN(10.0f, zoomFactor);
  583 + zoomFactor = MAX(1.0f, zoomFactor);
  584 +
  585 + self.device.videoZoomFactor = zoomFactor;
  586 + [self.device unlockForConfiguration];
  587 + }
  588 +}
  589 +#pragma mark - 对焦
  590 +/// 对焦
  591 +- (void)focusGesture:(UITapGestureRecognizer*)gesture
  592 +{
  593 + CGPoint point = [gesture locationInView:gesture.view];
  594 + [self focusAtPoint:point];
  595 +}
  596 +
  597 +- (void)focusAtPoint:(CGPoint)point
  598 +{
  599 + CGSize size = self.view.bounds.size;
  600 + // focusPoint 函数后面Point取值范围是取景框左上角(0,0)到取景框右下角(1,1)之间,按这个来但位置就是不对,只能按上面的写法才可以。前面是点击位置的y/PreviewLayer的高度,后面是1-点击位置的x/PreviewLayer的宽度
  601 + CGPoint focusPoint = CGPointMake( point.y /size.height ,1 - point.x/size.width );
  602 + NSError *error;
  603 + if ([self.device lockForConfiguration:&error]) {
  604 + if ([self.device isFocusModeSupported:AVCaptureFocusModeAutoFocus]) {
  605 + [self.device setFocusPointOfInterest:focusPoint];
  606 + [self.device setFocusMode:AVCaptureFocusModeAutoFocus];
  607 + }
  608 +
  609 + if ([self.device isExposureModeSupported:AVCaptureExposureModeAutoExpose ]) {
  610 + [self.device setExposurePointOfInterest:focusPoint];
  611 + // 曝光量调节
  612 + [self.device setExposureMode:AVCaptureExposureModeAutoExpose];
  613 + }
  614 +
  615 + [self.device unlockForConfiguration];
  616 + self.focusView.center = point;
  617 + self.focusView.hidden = NO;
  618 + [UIView animateWithDuration:0.3 animations:^{
  619 + self.focusView.transform = CGAffineTransformMakeScale(1.25, 1.25);
  620 + }completion:^(BOOL finished) {
  621 + [UIView animateWithDuration:0.5 animations:^{
  622 + self.focusView.transform = CGAffineTransformIdentity;
  623 + } completion:^(BOOL finished) {
  624 + self.focusView.hidden = YES;
  625 + }];
  626 + }];
  627 + }
  628 +}
  629 +
  630 +#pragma mark - 闪光灯
  631 +- (void)FlashOn
  632 +{
  633 + NSError *error;
  634 + if ([_device lockForConfiguration:&error]) {
  635 + if (_isflashOn) {
  636 + if ([_device isFlashModeSupported:AVCaptureFlashModeOff]) {
  637 + [_device setFlashMode:AVCaptureFlashModeOff];
  638 + _isflashOn = NO;
  639 +
  640 + }
  641 + }else{
  642 + if ([_device isFlashModeSupported:AVCaptureFlashModeOn]) {
  643 + [_device setFlashMode:AVCaptureFlashModeOn];
  644 + _isflashOn = YES;
  645 + }
  646 + }
  647 + [_device unlockForConfiguration];
  648 + }
  649 +}
  650 +
  651 +#pragma mark - 切换摄像头
  652 +
  653 +-(void)changeCamera
  654 +{
  655 + //获取摄像头的数量
  656 + NSUInteger cameraCount = [[AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo] count];
  657 + //摄像头小于等于1的时候直接返回
  658 + if (cameraCount <= 1) return;
  659 +
  660 + AVCaptureDevice *newCamera = nil;
  661 + AVCaptureDeviceInput *newInput = nil;
  662 + //获取当前相机的方向(前还是后)
  663 + AVCaptureDevicePosition position = [[self.input device] position];
  664 +
  665 + //为摄像头的转换加转场动画
  666 + CATransition *animation = [CATransition animation];
  667 + animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
  668 + animation.duration = 0.5;
  669 + animation.type = @"oglFlip";
  670 +
  671 + if (position == AVCaptureDevicePositionFront) {
  672 + //获取后置摄像头
  673 + newCamera = [self cameraWithPosition:AVCaptureDevicePositionBack];
  674 + animation.subtype = kCATransitionFromLeft;
  675 + }else{
  676 + //获取前置摄像头
  677 + newCamera = [self cameraWithPosition:AVCaptureDevicePositionFront];
  678 + animation.subtype = kCATransitionFromRight;
  679 + }
  680 +
  681 + [self.previewLayer addAnimation:animation forKey:nil];
  682 + //输入流
  683 + newInput = [AVCaptureDeviceInput deviceInputWithDevice:newCamera error:nil];
  684 +
  685 + if (newInput != nil) {
  686 +
  687 + [self.session beginConfiguration];
  688 + //先移除原来的input
  689 + [self.session removeInput:self.input];
  690 +
  691 + if ([self.session canAddInput:newInput]) {
  692 + [self.session addInput:newInput];
  693 + self.input = newInput;
  694 +
  695 + } else {
  696 + //如果不能加现在的input,就加原来的input
  697 + [self.session addInput:self.input];
  698 + }
  699 + [self.session commitConfiguration];
  700 + }
  701 +}
  702 +
  703 +- (AVCaptureDevice *)cameraWithPosition:(AVCaptureDevicePosition)position
  704 +{
  705 + NSArray *devices = [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo];
  706 + for ( AVCaptureDevice *device in devices )
  707 + if ( device.position == position ) return device;
  708 + return nil;
  709 +}
  710 +
  711 +#pragma mark - 拍照
  712 +/// 拍照
  713 +-(void)onTakePicture
  714 +{
  715 + AVCaptureConnection * videoConnection = [self.imageOutput connectionWithMediaType:AVMediaTypeVideo];
  716 + if (videoConnection == nil) return;
  717 + __weak typeof(self) weakSelf = self;
  718 + [self.imageOutput captureStillImageAsynchronouslyFromConnection:videoConnection completionHandler:^(CMSampleBufferRef imageDataSampleBuffer, NSError *error) {
  719 + if (imageDataSampleBuffer == NULL) return;
  720 + NSData * imageData = [AVCaptureStillImageOutput jpegStillImageNSDataRepresentation:imageDataSampleBuffer];
  721 + UIImage * image = [UIImage imageWithData:imageData];
  722 + [self stopVideoCapture];
  723 + [weakSelf openEditToolWithImg:image];
  724 + }];
  725 +}
  726 +
  727 +#pragma mark - 裁剪图片
  728 +/// 裁剪图片
  729 +-(void)openEditToolWithImg:(UIImage *)image
  730 +{
  731 + __weak typeof(self) weakSelf = self;
  732 + CNLiveCutImageToolView *tool = [CNLiveCutImageToolView showViewWithImg:image andSelectClipRatio:0];
  733 + // tool.cancelBlock = ^{
  734 + // /// 重拍
  735 + // [weakSelf onRetake];
  736 + // };
  737 + tool.finishBlock = ^(UIImage *image) {
  738 + /// 保存图片
  739 + weakSelf.takedImage = image;
  740 + [weakSelf requestWithImage:image type:@"2"];
  741 + };
  742 +}
  743 +
  744 +#pragma mark - 打开相册
  745 +-(void)openPhotoLibrary
  746 +{
  747 + // TZImagePickerController *imagePickerVC = [[TZImagePickerController alloc] initWithMaxImagesCount:1 delegate:nil];
  748 + // // 在内部显示拍照按钮
  749 + // imagePickerVC.allowTakePicture = false;
  750 + // // 设置是否可以选择视频
  751 + // imagePickerVC.allowPickingVideo = false;
  752 + // imagePickerVC.autoDismiss = false;
  753 + //
  754 + // WeakSelf;
  755 + // __weak typeof(imagePickerVC) weakVC = imagePickerVC;
  756 + // [imagePickerVC setDidFinishPickingPhotosHandle:^(NSArray<UIImage *> *photos, NSArray *assets, BOOL isSelectOriginalPhoto) {
  757 + // [weakSelf openEditToolWithImg:photos.lastObject];
  758 + // [weakVC dismissViewControllerAnimated:true completion:nil];
  759 + // }];
  760 + //
  761 + // [imagePickerVC setImagePickerControllerDidCancelHandle:^{
  762 + // [weakVC dismissViewControllerAnimated:true completion:nil];
  763 + // }];
  764 + //
  765 + // [self presentViewController:imagePickerVC animated:true completion:nil];
  766 +}
  767 +
  768 +
  769 +
  770 +//重新拍照或录制
  771 +- (void)onRetake
  772 +{
  773 + [self.session startRunning];
  774 + [self focusAtPoint:self.view.center];
  775 +
  776 + /// 摄像头缩放
  777 + NSError *error = nil;
  778 + [self.device lockForConfiguration:&error];
  779 + if (!error) {
  780 + self.device.videoZoomFactor = 1.0f;
  781 + [self.device unlockForConfiguration];
  782 + }
  783 +}
  784 +
  785 +#pragma mark - 请求测试
  786 +
  787 +- (void)requestWithImage:(UIImage *)image type:(NSString *)type{
  788 +
  789 + NSData *imageData = UIImageJPEGRepresentation(image, 1.0f);
  790 + NSString *encodedImageStr = [imageData base64EncodedStringWithOptions:NSDataBase64Encoding64CharacterLineLength];
  791 +
  792 + NSString *picStr = encodedImageStr;
  793 + picStr = [picStr stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]; //去除掉首尾的空白字符和换行字符
  794 + picStr = [picStr stringByReplacingOccurrencesOfString:@"\r" withString:@""];
  795 + picStr = [picStr stringByReplacingOccurrencesOfString:@"\n" withString:@""];
  796 + //str就是去掉的string
  797 +
  798 + NSDictionary *params = @{
  799 + @"activityId":@"27",
  800 + @"appid":@"NTY=",
  801 + @"appsecret":@"271c9c71d9c107997cf4074d652f4262",
  802 + @"picStr":picStr
  803 + }.copy;
  804 +
  805 + NSData *jsonData = [NSJSONSerialization dataWithJSONObject:params options:NSJSONWritingPrettyPrinted error:nil];
  806 + NSString *jsonString = [[NSString alloc]initWithData:jsonData encoding:NSUTF8StringEncoding];
  807 +
  808 + NSString *url = @"http://wmgjmewtest.iseasoon.com/mobile-web-user/ws/mobile/v1/active/scan";
  809 +
  810 +
  811 + AFURLSessionManager *manager = [[AFURLSessionManager alloc] initWithSessionConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]];
  812 + NSMutableURLRequest*request = [[AFHTTPRequestSerializer serializer]requestWithMethod:@"post" URLString:url parameters:nil error:nil];
  813 +
  814 + request.timeoutInterval=20;
  815 +
  816 + [request setValue:@"application/json"forHTTPHeaderField:@"Content-Type"];
  817 +
  818 + //设置body
  819 + NSData *data = [jsonString dataUsingEncoding:NSUTF8StringEncoding];
  820 + [request setHTTPBody:data];
  821 +
  822 + // AFHTTPResponseSerializer *responseSerializer = [AFHTTPResponseSerializer serializer];
  823 + // responseSerializer.acceptableContentTypes = [NSSet setWithObjects:@"application/json",
  824 + // @"text/html",
  825 + // @"text/json",
  826 + // @"text/javascript",
  827 + // @"text/plain",
  828 + // nil];
  829 + // manager.responseSerializer = responseSerializer;
  830 + [[manager dataTaskWithRequest:request uploadProgress:^(NSProgress * _Nonnull uploadProgress) {
  831 +
  832 + } downloadProgress:^(NSProgress * _Nonnull downloadProgress) {
  833 +
  834 + } completionHandler:^(NSURLResponse * _Nonnull response, id _Nullable responseObject, NSError * _Nullable error) {
  835 +
  836 + [self.imageView removeFromSuperview];
  837 +
  838 + self -> mGetPicture = NO;
  839 +
  840 + if (error) {
  841 + NSLog(@"有错误");
  842 + }else {
  843 + NSLog(@"没错误");
  844 + NSLog(@"输出内容%@",responseObject[@"msg"]);
  845 +
  846 + if ( [[NSString stringWithFormat:@"%@",responseObject[@"code"]] isEqualToString:@"1"]) {
  847 +
  848 + }else {
  849 + if ([type isEqualToString:@"2"]) {
  850 + [self startVideoCapture];
  851 + }
  852 +
  853 + }
  854 +
  855 + }
  856 +
  857 +
  858 +
  859 + }] resume];
  860 +
  861 +
  862 +
  863 +}
  864 +
  865 +- (NSString *)jsonToString:(id)data {
  866 + if(data == nil) { return nil; }
  867 + NSData *jsonData = [NSJSONSerialization dataWithJSONObject:data options:NSJSONWritingPrettyPrinted error:nil];
  868 + return [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
  869 +}
  870 +
  871 +
  872 +#pragma mark - 懒加载
  873 +- (UIImageView *)imageView {
  874 + if (!_imageView) {
  875 + _imageView = [[UIImageView alloc] initWithFrame:CGRectMake([UIScreen mainScreen].bounds.size.width - 200, 0,200, 200)];
  876 + [_imageView setBackgroundColor:[UIColor yellowColor]];
  877 + _imageView.contentMode = UIViewContentModeScaleToFill;
  878 + }
  879 + return _imageView;
  880 +
  881 +
  882 +}
  883 +
  884 +- (void)didReceiveMemoryWarning {
  885 + [super didReceiveMemoryWarning];
  886 + // Dispose of any resources that can be recreated.
  887 +}
  888 +
  889 +
  890 +@end
CNLiveScanGoodsCamera/Classes/ReplaceMe.m deleted 100644 → 0
Example/CNLiveScanGoodsCamera.xcodeproj/project.pbxproj
@@ -37,11 +37,11 @@ @@ -37,11 +37,11 @@
37 /* End PBXContainerItemProxy section */ 37 /* End PBXContainerItemProxy section */
38 38
39 /* Begin PBXFileReference section */ 39 /* Begin PBXFileReference section */
40 - 0219BFEFD039D44D84A6C11A /* CNLiveScanGoodsCamera.podspec */ = {isa = PBXFileReference; includeInIndex = 1; name = CNLiveScanGoodsCamera.podspec; path = ../CNLiveScanGoodsCamera.podspec; sourceTree = "<group>"; }; 40 + 0219BFEFD039D44D84A6C11A /* CNLiveScanGoodsCamera.podspec */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; name = CNLiveScanGoodsCamera.podspec; path = ../CNLiveScanGoodsCamera.podspec; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.ruby; };
41 02994EFFD2FA8A034AD1D0B9 /* Pods-CNLiveScanGoodsCamera_Example.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-CNLiveScanGoodsCamera_Example.release.xcconfig"; path = "Target Support Files/Pods-CNLiveScanGoodsCamera_Example/Pods-CNLiveScanGoodsCamera_Example.release.xcconfig"; sourceTree = "<group>"; }; 41 02994EFFD2FA8A034AD1D0B9 /* Pods-CNLiveScanGoodsCamera_Example.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-CNLiveScanGoodsCamera_Example.release.xcconfig"; path = "Target Support Files/Pods-CNLiveScanGoodsCamera_Example/Pods-CNLiveScanGoodsCamera_Example.release.xcconfig"; sourceTree = "<group>"; };
42 219C510B7AE998A3840A1604 /* Pods_CNLiveScanGoodsCamera_Example.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_CNLiveScanGoodsCamera_Example.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 42 219C510B7AE998A3840A1604 /* Pods_CNLiveScanGoodsCamera_Example.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_CNLiveScanGoodsCamera_Example.framework; sourceTree = BUILT_PRODUCTS_DIR; };
43 - 44D8FE3B8C9004785D9E092E /* README.md */ = {isa = PBXFileReference; includeInIndex = 1; name = README.md; path = ../README.md; sourceTree = "<group>"; };  
44 - 4B4229A5D728BDAC6B4394CD /* LICENSE */ = {isa = PBXFileReference; includeInIndex = 1; name = LICENSE; path = ../LICENSE; sourceTree = "<group>"; }; 43 + 44D8FE3B8C9004785D9E092E /* README.md */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = net.daringfireball.markdown; name = README.md; path = ../README.md; sourceTree = "<group>"; };
  44 + 4B4229A5D728BDAC6B4394CD /* LICENSE */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; name = LICENSE; path = ../LICENSE; sourceTree = "<group>"; };
45 6003F58A195388D20070C39A /* CNLiveScanGoodsCamera_Example.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = CNLiveScanGoodsCamera_Example.app; sourceTree = BUILT_PRODUCTS_DIR; }; 45 6003F58A195388D20070C39A /* CNLiveScanGoodsCamera_Example.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = CNLiveScanGoodsCamera_Example.app; sourceTree = BUILT_PRODUCTS_DIR; };
46 6003F58D195388D20070C39A /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; 46 6003F58D195388D20070C39A /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
47 6003F58F195388D20070C39A /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; 47 6003F58F195388D20070C39A /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; };
@@ -193,7 +193,6 @@ @@ -193,7 +193,6 @@
193 9C1C101E0458C2E2EE15B370 /* Pods-CNLiveScanGoodsCamera_Tests.debug.xcconfig */, 193 9C1C101E0458C2E2EE15B370 /* Pods-CNLiveScanGoodsCamera_Tests.debug.xcconfig */,
194 E2A9C3755B8BC2060481853A /* Pods-CNLiveScanGoodsCamera_Tests.release.xcconfig */, 194 E2A9C3755B8BC2060481853A /* Pods-CNLiveScanGoodsCamera_Tests.release.xcconfig */,
195 ); 195 );
196 - name = Pods;  
197 path = Pods; 196 path = Pods;
198 sourceTree = "<group>"; 197 sourceTree = "<group>";
199 }; 198 };
@@ -248,6 +247,9 @@ @@ -248,6 +247,9 @@
248 LastUpgradeCheck = 0720; 247 LastUpgradeCheck = 0720;
249 ORGANIZATIONNAME = "梁星国"; 248 ORGANIZATIONNAME = "梁星国";
250 TargetAttributes = { 249 TargetAttributes = {
  250 + 6003F589195388D20070C39A = {
  251 + DevelopmentTeam = 94X49GG3ZW;
  252 + };
251 6003F5AD195388D20070C39A = { 253 6003F5AD195388D20070C39A = {
252 TestTargetID = 6003F589195388D20070C39A; 254 TestTargetID = 6003F589195388D20070C39A;
253 }; 255 };
@@ -258,6 +260,7 @@ @@ -258,6 +260,7 @@
258 developmentRegion = English; 260 developmentRegion = English;
259 hasScannedForEncodings = 0; 261 hasScannedForEncodings = 0;
260 knownRegions = ( 262 knownRegions = (
  263 + English,
261 en, 264 en,
262 Base, 265 Base,
263 ); 266 );
@@ -302,10 +305,14 @@ @@ -302,10 +305,14 @@
302 ); 305 );
303 inputPaths = ( 306 inputPaths = (
304 "${PODS_ROOT}/Target Support Files/Pods-CNLiveScanGoodsCamera_Example/Pods-CNLiveScanGoodsCamera_Example-frameworks.sh", 307 "${PODS_ROOT}/Target Support Files/Pods-CNLiveScanGoodsCamera_Example/Pods-CNLiveScanGoodsCamera_Example-frameworks.sh",
  308 + "${BUILT_PRODUCTS_DIR}/AFNetworking/AFNetworking.framework",
  309 + "${BUILT_PRODUCTS_DIR}/CNLiveRequestBastKit/CNLiveRequestBastKit.framework",
305 "${BUILT_PRODUCTS_DIR}/CNLiveScanGoodsCamera/CNLiveScanGoodsCamera.framework", 310 "${BUILT_PRODUCTS_DIR}/CNLiveScanGoodsCamera/CNLiveScanGoodsCamera.framework",
306 ); 311 );
307 name = "[CP] Embed Pods Frameworks"; 312 name = "[CP] Embed Pods Frameworks";
308 outputPaths = ( 313 outputPaths = (
  314 + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/AFNetworking.framework",
  315 + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/CNLiveRequestBastKit.framework",
309 "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/CNLiveScanGoodsCamera.framework", 316 "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/CNLiveScanGoodsCamera.framework",
310 ); 317 );
311 runOnlyForDeploymentPostprocessing = 0; 318 runOnlyForDeploymentPostprocessing = 0;
@@ -494,6 +501,7 @@ @@ -494,6 +501,7 @@
494 baseConfigurationReference = E9D98969971014AB6E456E8F /* Pods-CNLiveScanGoodsCamera_Example.debug.xcconfig */; 501 baseConfigurationReference = E9D98969971014AB6E456E8F /* Pods-CNLiveScanGoodsCamera_Example.debug.xcconfig */;
495 buildSettings = { 502 buildSettings = {
496 ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 503 ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
  504 + DEVELOPMENT_TEAM = 94X49GG3ZW;
497 GCC_PRECOMPILE_PREFIX_HEADER = YES; 505 GCC_PRECOMPILE_PREFIX_HEADER = YES;
498 GCC_PREFIX_HEADER = "CNLiveScanGoodsCamera/CNLiveScanGoodsCamera-Prefix.pch"; 506 GCC_PREFIX_HEADER = "CNLiveScanGoodsCamera/CNLiveScanGoodsCamera-Prefix.pch";
499 INFOPLIST_FILE = "CNLiveScanGoodsCamera/CNLiveScanGoodsCamera-Info.plist"; 507 INFOPLIST_FILE = "CNLiveScanGoodsCamera/CNLiveScanGoodsCamera-Info.plist";
@@ -510,6 +518,7 @@ @@ -510,6 +518,7 @@
510 baseConfigurationReference = 02994EFFD2FA8A034AD1D0B9 /* Pods-CNLiveScanGoodsCamera_Example.release.xcconfig */; 518 baseConfigurationReference = 02994EFFD2FA8A034AD1D0B9 /* Pods-CNLiveScanGoodsCamera_Example.release.xcconfig */;
511 buildSettings = { 519 buildSettings = {
512 ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 520 ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
  521 + DEVELOPMENT_TEAM = 94X49GG3ZW;
513 GCC_PRECOMPILE_PREFIX_HEADER = YES; 522 GCC_PRECOMPILE_PREFIX_HEADER = YES;
514 GCC_PREFIX_HEADER = "CNLiveScanGoodsCamera/CNLiveScanGoodsCamera-Prefix.pch"; 523 GCC_PREFIX_HEADER = "CNLiveScanGoodsCamera/CNLiveScanGoodsCamera-Prefix.pch";
515 INFOPLIST_FILE = "CNLiveScanGoodsCamera/CNLiveScanGoodsCamera-Info.plist"; 524 INFOPLIST_FILE = "CNLiveScanGoodsCamera/CNLiveScanGoodsCamera-Info.plist";
Example/CNLiveScanGoodsCamera/CNLIVEViewController.m
@@ -7,9 +7,12 @@ @@ -7,9 +7,12 @@
7 // 7 //
8 8
9 #import "CNLIVEViewController.h" 9 #import "CNLIVEViewController.h"
  10 +#import "CNLiveScanGoodsCameraController.h"
10 11
11 @interface CNLIVEViewController () 12 @interface CNLIVEViewController ()
12 13
  14 +@property (strong, nonatomic) UIButton *enterBtn;
  15 +
13 @end 16 @end
14 17
15 @implementation CNLIVEViewController 18 @implementation CNLIVEViewController
@@ -18,6 +21,23 @@ @@ -18,6 +21,23 @@
18 { 21 {
19 [super viewDidLoad]; 22 [super viewDidLoad];
20 // Do any additional setup after loading the view, typically from a nib. 23 // Do any additional setup after loading the view, typically from a nib.
  24 +
  25 + [self.view addSubview:self.enterBtn];
  26 +
  27 + [self.enterBtn addTarget:self action:@selector(buttonAction:) forControlEvents:UIControlEventTouchUpInside];
  28 +
  29 +
  30 +}
  31 +
  32 +- (void)buttonAction:(UIButton *)sender {
  33 + CNLiveScanGoodsCameraController *vc = [[CNLiveScanGoodsCameraController alloc]init];
  34 + vc.modalPresentationStyle = UIModalPresentationFullScreen;
  35 + [self presentViewController:vc animated:YES completion:^{
  36 +
  37 + }];
  38 +
  39 +
  40 +
21 } 41 }
22 42
23 - (void)didReceiveMemoryWarning 43 - (void)didReceiveMemoryWarning
@@ -26,4 +46,16 @@ @@ -26,4 +46,16 @@
26 // Dispose of any resources that can be recreated. 46 // Dispose of any resources that can be recreated.
27 } 47 }
28 48
  49 +
  50 +- (UIButton *)enterBtn {
  51 + if (!_enterBtn) {
  52 + _enterBtn = [UIButton buttonWithType:UIButtonTypeCustom];
  53 + _enterBtn.frame = CGRectMake(100, 100, 100, 100);
  54 + [_enterBtn setBackgroundColor:[UIColor yellowColor]];
  55 + }
  56 +
  57 + return _enterBtn;;
  58 +}
  59 +
  60 +
29 @end 61 @end
Example/CNLiveScanGoodsCamera/CNLiveScanGoodsCamera-Info.plist
@@ -2,8 +2,35 @@ @@ -2,8 +2,35 @@
2 <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> 2 <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3 <plist version="1.0"> 3 <plist version="1.0">
4 <dict> 4 <dict>
  5 + <key>NSBluetoothAlwaysUsageDescription</key>
  6 + <string>需要允许开启蓝牙才能对音箱使用配对及配网功能</string>
  7 + <key>NSBluetoothPeripheralUsageDescription</key>
  8 + <string>需要允许开启蓝牙才能对音箱使用配对及配网功能</string>
  9 + <key>NSCameraUsageDescription</key>
  10 + <string>需要允许开启相机才能在发布生活圈或聊天时使用录制视频和拍照功能</string>
  11 + <key>NSContactsUsageDescription</key>
  12 + <string>需要允许访问通讯录才能获取手机联系人中的网家家用户</string>
  13 + <key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
  14 + <string>需要允许使用您的位置信息才能获取您所在的城市</string>
  15 + <key>NSLocationAlwaysUsageDescription</key>
  16 + <string>需要允许使用您的位置信息才能获取您所在的城市</string>
  17 + <key>NSLocationWhenInUseUsageDescription</key>
  18 + <string>需要允许使用您的位置信息才能获取您所在的城市</string>
  19 + <key>NSMicrophoneUsageDescription</key>
  20 + <string>需要允许开启麦克风才能使用录制视频和语音等服务</string>
  21 + <key>NSMotionUsageDescription</key>
  22 + <string>需要允许访问运动与健身才能在参加线上跑步赛事时记录您的步数信息</string>
  23 + <key>NSPhotoLibraryAddUsageDescription</key>
  24 + <string>需要允许打开相册才能访问相册照片和保存照片</string>
  25 + <key>NSPhotoLibraryUsageDescription</key>
  26 + <string>需要允许打开相册才能访问相册照片和保存照片</string>
5 <key>CFBundleDevelopmentRegion</key> 27 <key>CFBundleDevelopmentRegion</key>
6 <string>en</string> 28 <string>en</string>
  29 + <key>NSAppTransportSecurity</key>
  30 + <dict>
  31 + <key>NSAllowsArbitraryLoads</key>
  32 + <true/>
  33 + </dict>
7 <key>CFBundleDisplayName</key> 34 <key>CFBundleDisplayName</key>
8 <string>${PRODUCT_NAME}</string> 35 <string>${PRODUCT_NAME}</string>
9 <key>CFBundleExecutable</key> 36 <key>CFBundleExecutable</key>
Example/Podfile
1 use_frameworks! 1 use_frameworks!
2 2
3 -platform :ios, '8.0' 3 +platform :ios, '9.0'
  4 +
  5 +source 'https://mirrors.tuna.tsinghua.edu.cn/git/CocoaPods/Specs.git'
  6 +#source 'https://github.com/CocoaPods/Specs.git'
  7 +source 'http://bj.gitlab.cnlive.com/ios-team/CNLiveRepos.git'
  8 +source 'http://bj.gitlab.cnlive.com/DSIOSTeam/DSSpecRepos.git'
4 9
5 target 'CNLiveScanGoodsCamera_Example' do 10 target 'CNLiveScanGoodsCamera_Example' do
6 pod 'CNLiveScanGoodsCamera', :path => '../' 11 pod 'CNLiveScanGoodsCamera', :path => '../'