Commit 7474ee25 authored by jz's avatar jz

add controllers

parent 5249babb
//
// GMCameraFaceView.swift
// Gengmei
//
// Created by 刘鹿杰 on 2019/8/17.
// Copyright © 2019 更美互动信息科技有限公司. All rights reserved.
//
import Foundation
class GMCameraFaceView: GMView {
//捕获设备,通常是前置摄像头,后置摄像头,麦克风(音频输入)
var device: AVCaptureDevice!
//AVCaptureDeviceInput 代表输入设备,他使用AVCaptureDevice 来初始化
fileprivate var input: AVCaptureDeviceInput!
//当启动摄像头开始捕获输入
fileprivate var output: AVCaptureMetadataOutput!
var ImageOutPut: AVCaptureStillImageOutput!
//session:由他把输入输出结合在一起,并开始启动捕获设备(摄像头)
var session: AVCaptureSession!
//图像预览层,实时显示捕获的图像
fileprivate var previewLayer: AVCaptureVideoPreviewLayer!
// 创建中间动画View
fileprivate var animationView: NewFaceScanAnimationView!
// 拍照按钮
fileprivate var shotButton: GMButton!
// 选择相册按钮
fileprivate var albumButton: UIButton!
override func setup() {
customCamera()
setupSubviews()
}
func customCamera() {
if !self.canUseCamera() {
return
}
if Platform.isSimulator {
return
}
// 使用AVMediaTypeVideo 指明self.device代表视频,默认使用后置摄像头进行初始化
self.device = AVCaptureDevice.default(for: AVMediaType.video)
// 尝试获取前置摄像头
for device in AVCaptureDevice.devices(for: AVMediaType.video) where (device as AnyObject).position == .front {
self.device = device
break
}
//使用设备初始化输入
do {
self.input = try AVCaptureDeviceInput(device: self.device)
} catch _ {
}
//生成输出对象
self.output = AVCaptureMetadataOutput()
self.ImageOutPut = AVCaptureStillImageOutput()
//生成会话,用来结合输入输出
self.session = AVCaptureSession()
if self.session.canSetSessionPreset(AVCaptureSession.Preset.hd1280x720) {
self.session.sessionPreset = AVCaptureSession.Preset.hd1280x720
}
if self.session.canAddInput(self.input) {
self.session.addInput(self.input)
}
if self.session.canAddOutput(self.ImageOutPut) {
self.session.addOutput(self.ImageOutPut)
}
//使用self.session,初始化预览层,self.session负责驱动input进行信息的采集,layer负责把图像渲染显示
self.previewLayer = AVCaptureVideoPreviewLayer(session: self.session)
self.previewLayer.frame = CGRect(x: 0, y: 0, width: Constant.screenWidth, height: Constant.screenHeight)
self.previewLayer.videoGravity = AVLayerVideoGravity.resizeAspectFill
self.layer.insertSublayer(self.previewLayer, at: 0)
//开始启动
self.session.startRunning()
do {
try device.lockForConfiguration()
} catch _ {
print("lockForConfiguration failed")
}
if device.isFlashModeSupported(.off) {
device.flashMode = .off
}
//自动白平衡
if device.isWhiteBalanceModeSupported(.autoWhiteBalance) {
device.whiteBalanceMode = .autoWhiteBalance
}
device.unlockForConfiguration()
}
// 改变照相机拍摄方向
func changeCamera() {
if !canUseCamera() {
return
}
let cameraCount = AVCaptureDevice.devices(for: AVMediaType.video).count
if cameraCount <= 1 {
return
}
var newCamera: AVCaptureDevice?
var newInput: AVCaptureDeviceInput?
if input.device.position == .front {
newCamera = self.cameraWithPosition(.back)
// navigationBar.nearRightButton.isHidden = false
} else {
newCamera = self.cameraWithPosition(.front)
// navigationBar.nearRightButton.isHidden = true
}
do {
newInput = try AVCaptureDeviceInput(device: newCamera!)
} catch let error {
print("toggle carema failed, error = \(error)")
}
if newInput != nil {
session.beginConfiguration()
session.removeInput(input)
if session.canAddInput(newInput!) {
session.addInput(newInput!)
input = newInput
device = newCamera
} else {
session.addInput(self.input)
}
session.commitConfiguration()
}
}
// 是否可以使用照相机
func canUseCamera() -> Bool {
let status = AVCaptureDevice.authorizationStatus(for: AVMediaType.video)
if status == .denied {
return false
} else if status == .notDetermined {
AVCaptureDevice.requestAccess(for: AVMediaType.video, completionHandler: { (result) in
if result {
// uiThread {
self.customCamera()
// }
}
})
return false
} else {
return true
}
}
func cameraWithPosition(_ position: AVCaptureDevice.Position) -> AVCaptureDevice? {
let devices = AVCaptureDevice.devices(for: AVMediaType.video)
for device in devices where (device as AnyObject).position == position {
return device
}
return nil
}
@objc func image(_ image: UIImage, didFinishSavingWithError error: NSError?, contextInfo: UnsafeMutableRawPointer) {
}
// 设置UI
func setupSubviews() {
// 添加动画View
animationView = NewFaceScanAnimationView(frame: self.bounds)
self.addSubview(animationView)
animationView.beginAnimation()
// 拍照按钮
shotButton = GMButton(type: .custom)
shotButton.setImage(UIImage(named: "NewFaceShotButton"), for: .normal)
shotButton.addTarget(self, action: #selector(NewFaceShotController.shotAction), for: .touchUpInside)
self.addSubview(shotButton)
// 选择照片
albumButton = UIButton(type: .custom)
GMNewFaceTool.latestImage { (image) in
if image == nil {
DispatchQueue.main.async {
self.albumButton.setImage(UIImage(named: "NewFacePhotoNone"), for: .normal)
self.albumButton.setImage(UIImage(named: "NewFacePhotoNone"), for: .highlighted)
}
} else {
DispatchQueue.main.async {
self.albumButton.setImage(image, for: .normal)
self.albumButton.setImage(image, for: .highlighted)
}
}
}
albumButton.addTarget(self, action: #selector(NewFaceShotController.ablumAction), for: .touchUpInside)
albumButton.layer.cornerRadius = 4
albumButton.layer.masksToBounds = true
albumButton.layer.borderWidth = 1
albumButton.layer.borderColor = UIColor.white.cgColor
albumButton.imageView?.contentMode = .scaleAspectFill
self.addSubview(albumButton)
// 设置拍照按钮动画
let centerAnimate = CABasicAnimation(keyPath: "transform.rotation.z")
centerAnimate.toValue = Double.pi * 2.0
centerAnimate.duration = 2.5
centerAnimate.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionLinear)
centerAnimate.repeatCount = Float(LLONG_MAX)
shotButton.layer.add(centerAnimate, forKey: "rotation")
// 更新布局约束
setupSubviewsConstraints()
}
func setupSubviewsConstraints() {
animationView.snp.makeConstraints { (make) in
make.edges.equalTo(UIEdgeInsets.zero)
}
shotButton.snp.makeConstraints { (make) in
make.bottom.equalTo(-52 - UIView.safeAreaInsetsBottom)
make.centerX.equalToSuperview()
make.size.equalTo(CGSize(width: 70, height: 70))
}
albumButton.snp.makeConstraints { (make) in
make.centerY.equalTo(shotButton)
make.centerX.equalTo(shotButton).offset(-Constant.screenWidth*0.25-12)
make.size.equalTo(CGSize(width: 46, height: 46))
}
}
}
//
// GMGeneMemoryAnimationViewController.h
// Gengmei
//
// Created by 朱璇 on 2019/12/6.
// Copyright © 2019 更美互动信息科技有限公司. All rights reserved.
//
NS_ASSUME_NONNULL_BEGIN
@interface GMGeneMemoryAnimationViewController : WMBaseViewController
@property (nonatomic, strong) UIImage *image;
@property (nonatomic, assign) NSInteger gender;
@end
NS_ASSUME_NONNULL_END
//
// GMGeneMemoryAnimationViewController.m
// Gengmei
//
// Created by 朱璇 on 2019/12/6.
// Copyright © 2019 更美互动信息科技有限公司. All rights reserved.
//
#import "GMGeneMemoryAnimationViewController.h"
#import "ALFaceInfoViewModel.h"
#import "UIImage+GMExtension.h"
#import "GMFaceV3Util.h"
#import "NSString+jsonData.h"
#import "GMFacePointViewController.h"
#import "Lottie.h"
#define centerPoint CGPointMake(MAINSCREEN_WIDTH / 2, MAINSCREEN_HEIGHT / 2)
#define fromRadius sqrtf((centerPoint.x * centerPoint.x) + (centerPoint.y * centerPoint.y))
#define toRadius (92.0 / 375 * MAINSCREEN_WIDTH)
#define circleRadius (80.0 / 375 * MAINSCREEN_WIDTH)
#define showAnimaitionTime .35
#define hideAnimaitionTime .35
#define circleAnimaitionTime 2
@interface GMGeneMemoryAnimationViewController () {
UIImageView *_bgImage;
UIImageView *_photoImage;
CAShapeLayer *_maskLayer;
}
@property (nonatomic, strong) LOTAnimationView *animationView;
@end
@implementation GMGeneMemoryAnimationViewController
-(void)initController{
[super initController];
self.navigationBar.backgroundColor = UIColor.clearColor;
self.navigationBar.titleLabel.textColor = UIColor.whiteColor;
self.navigationBar.leftIcon = @"NewFaceBack";
self.navigationBar.isShowShadow = NO;
}
- (void)viewDidLoad {
[super viewDidLoad];
self.extraParam = [NSString jsonStringWithObject:@{@"land_tab_name" : @"AI面孔"}];
[self setUp];
}
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
[self startShowPhotoAnimation];
}
-(void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
[self removeAnimation];
}
- (void)setUp {
UIImage *newImage = [self.image normalizedImage]; // 防止iOS 13 图片自动旋转90度
// 上传图片 并请求测试结果
__weak __typeof(self)weakSelf = self;
[GMFaceV3Util uploadOneImageToQiNiu:newImage gender:self.gender vc:self successBlock:^(id responseObject) {
[weakSelf startHidePhotoAnimation];
[weakSelf performSelector:@selector(pushToNextVC:) withObject:responseObject afterDelay:.8];
}];
_bgImage = [[UIImageView alloc] init];
_bgImage.image = [UIImage imageNamed:@"gene_loading_bg"];
_bgImage.contentMode = UIViewContentModeScaleAspectFill;
_bgImage.frame = self.view.frame;
[self.view addSubview:_bgImage];
_maskLayer = [CAShapeLayer layer];
_maskLayer.bounds = self.view.bounds;
_maskLayer.fillColor = [UIColor greenColor].CGColor; // Any color but clear will be OK
_maskLayer.path = [UIBezierPath bezierPathWithArcCenter:centerPoint radius:fromRadius startAngle:0 endAngle:2 * M_PI clockwise:YES].CGPath;
_maskLayer.opacity = 1;
_maskLayer.position = centerPoint;
_photoImage = [[UIImageView alloc] init];
_photoImage.contentMode = UIViewContentModeScaleAspectFill;
_photoImage.frame = self.view.frame;
_photoImage.image = newImage;
_photoImage.layer.mask = _maskLayer;
[self.view addSubview:_photoImage];
}
- (LOTAnimationView *)animationView {
if (!_animationView) {
_animationView = [LOTAnimationView animationNamed:@"gene_loading"];
_animationView.contentMode = UIViewContentModeScaleAspectFit;
_animationView.loopAnimation = YES;
_animationView.frame = CGRectMake(0, 85, 177, 60);
_animationView.centerX = centerPoint.x;
[self.view addSubview:_animationView];
}
return _animationView;
}
- (void)removeAnimation {
[_maskLayer removeAllAnimations];
[_animationView stop];
}
- (void)startShowPhotoAnimation {
CGPathRef fromPath = _maskLayer.path;
CGPathRef toPath = [UIBezierPath bezierPathWithArcCenter:centerPoint radius:toRadius startAngle:0 endAngle:2 * M_PI clockwise:YES].CGPath;
CABasicAnimation *pathAnimation = [CABasicAnimation animationWithKeyPath:@"path"];
pathAnimation.fromValue = (__bridge id _Nullable)(fromPath);
pathAnimation.toValue = (__bridge id _Nullable)(toPath);
pathAnimation.duration = showAnimaitionTime;
_maskLayer.path = toPath;
[_maskLayer addAnimation:pathAnimation forKey:@"path"];
[self performSelector:@selector(startCircleAnimation) withObject:nil afterDelay:showAnimaitionTime];
}
- (void)startCircleAnimation {
// 开始头部动画
[self.animationView playFromProgress:0 toProgress:1 withCompletion:^(BOOL animationFinished) {}];
CAKeyframeAnimation *pathAnimation = [CAKeyframeAnimation animationWithKeyPath:@"position"];
pathAnimation.calculationMode = kCAAnimationCubicPaced;
pathAnimation.fillMode = kCAFillModeForwards;
pathAnimation.removedOnCompletion = NO;
pathAnimation.duration = circleAnimaitionTime;
pathAnimation.repeatCount = OPEN_MAX;
CGMutablePathRef curvedPath = CGPathCreateMutable();
//center为圆心,circleRadius为半径 (startAngle,endAngle)为起始角度和结束角度,0为顺时针,1 为逆时针
CGPathAddArc(curvedPath, NULL, centerPoint.x + circleRadius / 2, centerPoint.y, circleRadius / 2, M_PI, 2 * M_PI, 0);
CGPathAddArc(curvedPath, NULL, centerPoint.x, centerPoint.y, circleRadius, 0, M_PI, 0);
CGPathAddArc(curvedPath, NULL, centerPoint.x - circleRadius / 2, centerPoint.y, circleRadius / 2, M_PI, 2 * M_PI, 0);
pathAnimation.path = curvedPath;
CGPathRelease(curvedPath);
[_maskLayer addAnimation:pathAnimation forKey:@"position"];
}
- (void)startHidePhotoAnimation {
// 删除动画
[self.animationView stop];
[self.animationView removeFromSuperview];
CGPathRef fromPath = _maskLayer.path;
CGPathRef toPath = [UIBezierPath bezierPathWithArcCenter:centerPoint radius:fromRadius * 2 startAngle:0 endAngle:2 * M_PI clockwise:YES].CGPath;
CABasicAnimation *pathAnimation = [CABasicAnimation animationWithKeyPath:@"path"];
pathAnimation.fromValue = (__bridge id _Nullable)(fromPath);
pathAnimation.toValue = (__bridge id _Nullable)(toPath);
pathAnimation.duration = hideAnimaitionTime;
_maskLayer.path = toPath;
[_maskLayer addAnimation:pathAnimation forKey:@"path"];
}
- (void)pushToNextVC:(id)objcet {
GMFaceV3Model *faceModel = (GMFaceV3Model *)objcet;
GMFacePointViewController *pointVc = [[GMFacePointViewController alloc] initWithModel:faceModel];
pointVc.isGene = YES;
[self.navigationController pushViewController:pointVc animated:YES];
}
@end
//
// GMGeneMemoryResultViewController.h
// Gengmei
//
// Created by 朱璇 on 2019/12/6.
// Copyright © 2019 更美互动信息科技有限公司. All rights reserved.
//
#import "GMBaseWebViewController.h"
NS_ASSUME_NONNULL_BEGIN
@interface GMGeneMemoryResultViewController : GMBaseWebViewController
@property(nonatomic, copy)NSString *webPath; // 需要加载的URL
@end
NS_ASSUME_NONNULL_END
//
// GMGeneMemoryResultViewController.m
// Gengmei
//
// Created by 朱璇 on 2019/12/6.
// Copyright © 2019 更美互动信息科技有限公司. All rights reserved.
//
#import "GMGeneMemoryResultViewController.h"
#import "ALShareSheet.h"
@interface GMGeneMemoryResultViewController ()<WKWebViewDelegate, GMClientH5BridgeDelegate>
@property (nonatomic, strong) NSDictionary *dataDict;
@property (nonatomic, strong) UIImage *shareImage; // 前端传递过来的图片
@property (nonatomic, strong) GMImageView *shareImageView; // 分享展示的图片
@property (nonatomic, strong) ALShareSheet *shareSheet; // 分享弹出框
@property (nonatomic, copy) NSString *imUrl;
@end
@implementation GMGeneMemoryResultViewController
- (void)initController {
[super initController];
// self.pageName = @"face_institute_report";
self.navigationBar.backgroundColor = UIColor.clearColor;
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
[self preferredStatusBarStyle];
[UIApplication sharedApplication].statusBarStyle = UIStatusBarStyleLightContent;
[UIApplication sharedApplication].statusBarHidden = YES;
}
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
[UIApplication sharedApplication].statusBarStyle = UIStatusBarStyleDefault;
[UIApplication sharedApplication].statusBarHidden = NO;
}
- (void)viewDidLoad {
[super viewDidLoad];
self.controlNavigationByYou = YES;
self.navigationBar.hidden = YES;
self.fd_interactivePopDisabled = YES;
self.webCompent.delegate = self;
self.webCompent.clientH5Object.delegate = self;
[self.webCompent mas_updateConstraints:^(MASConstraintMaker *make) {
make.edges.mas_equalTo(0);
}];
if (_webPath.length > 0) {
self.webCompent.fullUrl = [NSString stringWithFormat:@"%@%@",GMServerDomains.apiHost, _webPath];
} else {
self.webCompent.fullUrl = [NSString stringWithFormat:@"%@%@",GMServerDomains.apiHost, API_AI_RESEARCH_REPORT];
}
[self.webCompent webviewLoad:self];
}
- (void)setWebPath:(NSString *)webPath {
_webPath = webPath;
}
#pragma mark - 前端与移动端连调方法
- (void)jsGlobalDataLoaded:(NSString *)jsonString {
NSData *jsonData = [jsonString dataUsingEncoding:NSUTF8StringEncoding];
_jsGlobalObject = [NSJSONSerialization JSONObjectWithData:jsonData options:NSJSONReadingMutableContainers error:nil];
if (_jsGlobalObject == nil) {
return;
}
if (_jsGlobalObject[@"page_name"]) {
self.pageName = _jsGlobalObject[@"page_name"];
}
// 调取前端方法
NSDictionary *responseDict = [GMCache fetchObjectAtDocumentPathWithkey:kGMGeneMemoryLastData];
NSString *dictStr = [NSString convertToPrettyPrintedJsonString: responseDict];
NSNumber *gender = [GMCache fetchObjectAtDocumentPathWithkey:kGMGeneMemoryGender];
NSString *javaScriptStr = [NSString stringWithFormat:@"window.gm.pack.run('jsPageRenderData',%@, %d)", dictStr, gender.intValue];
[self.webCompent.webView evaluateJavaScript:javaScriptStr completionHandler:nil];
}
-(void)jsControlBackToMethod:(NSString *)str {
if([str isEqualToString:@"pop"]){ // 返回到拍照测试页面
[self backFurther];
} else if ([str isEqualToString:@"face"]) { // 返回测脸页面
[[NSNotificationCenter defaultCenter] postNotificationName:@"GMTestSkinAnimationWebViewSenBack" object:nil];
[self backFurther];
} else if ([str isEqualToString:@"reserch"]) { // 返回面孔起源
[self backFurther];
} else if ([str isEqualToString:@"skin"]) { // 测肤
[[NSNotificationCenter defaultCenter] postNotificationName:@"GMFaceInfoSharePopToFaceSkin" object:nil];
[self backFurther];
} else if ([str isEqualToString:@"back"]) { // 返回上一页
[self.navigationController popViewControllerAnimated:YES];
}
}
- (void)jsJumpToResearchPage:(NSString *)url {
GMGeneMemoryResultViewController *geneListVC = [[GMGeneMemoryResultViewController alloc] init];
geneListVC.webPath = url;
[self.navigationController pushViewController:geneListVC animated:YES];
}
- (NSString *)jsGetLocalStorage:(NSString *)key {
NSString *cacheKey = [GMCache fetchObjectAtDocumentPathWithkey:key];
NSString *javaScriptStr = [NSString stringWithFormat:@"window.gm.pack.run('getLocalStorage','%@')",cacheKey];
[self.webCompent.webView evaluateJavaScript:javaScriptStr completionHandler:nil];
if (![cacheKey isNonEmpty]) {
return @"";
}
return cacheKey;
}
// 当图片生成时,前端会调用这个方法
- (void)shareResearchInfoImageMethod:(NSString *)imageDataStr{
_shareImage = [self stringToImageWith:imageDataStr imageStr:@"imageString"];
if (!_shareImage) {
[self toast:@"糟糕,生成失败了,再试一次吧"];
return;
}
// 展示分享框
[self shareFaceInfo];
// 保存图片到相册
UIImageWriteToSavedPhotosAlbum(_shareImage, self, @selector(image:didFinishSavingWithError:contextInfo:), nil);
[self toast:@"图片已存至相册,快分享给朋友炫耀一下"];
}
// 解析前端传递过来的图片
- (UIImage *)stringToImageWith:(NSString *)imageData imageStr:(NSString *)imageStr {
NSData *jsonData = [imageData dataUsingEncoding:NSUTF8StringEncoding];
NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:jsonData options:NSJSONReadingMutableContainers error:nil];
NSString *imageString = dict[imageStr] ?: @"";
UIImage *image = [UIImage imageWithData:[[NSData alloc] initWithBase64EncodedString:imageString options:NSDataBase64DecodingIgnoreUnknownCharacters]];
return image;
}
- (void)shareFaceInfo {
CGFloat scale1 = _shareImage.size.height / _shareImage.size.width;
CGFloat width1 = ShareImageHeight / scale1;
self.shareImageView.image = self.shareImage;
self.shareImageView.frame = CGRectMake((MAINSCREEN_WIDTH - width1)/2, OCNavigationBar.barHeight + 10, width1, ShareImageHeight);
[self.shareSheet addSubview:self.shareImageView];
[self.shareSheet show];
[UIView animateWithDuration:0.5 animations:^{
_shareImageView.alpha = 1.0;
}];
}
- (void)image:(UIImage *)image didFinishSavingWithError:(NSError *)error contextInfo:(void *)contextInfo {}
// 返回按钮点击事件
-(void)backFurther {
BOOL isPop = YES;
for (UIViewController *vc in AppDelegate.navigation.childViewControllers) {
if ([vc isKindOfClass:[NewFaceShotController class]]){
isPop = NO;
[AppDelegate.navigation popToViewController:vc animated:YES];
return;
}
}
if (isPop) {
[AppDelegate.navigation popToRootViewControllerAnimated:YES];
}
}
- (UIStatusBarStyle)preferredStatusBarStyle {
return UIStatusBarStyleLightContent;
}
#pragma mark - 懒加载数据
- (ALShareSheet *)shareSheet {
if (!_shareSheet) {
_shareSheet = [[ALShareSheet alloc] init];
_shareSheet.bgAlphaColor = RGBCOLOR_HEX(0xF4F3F8);
__weak typeof(self) weakSelf = self;
_shareSheet.hiddenBlock = ^{ // 隐藏
[UIView animateWithDuration:0.25 animations:^{
weakSelf.shareImageView.alpha = 0.0;
} completion:^(BOOL finished) {
[weakSelf.shareImageView removeFromSuperview];
}];
};
_shareSheet.shareTypeBlock = ^(GMSharePlatform platform) { // 分享
[[GMShareSDK shareInstance] shareImage:weakSelf.shareImage platform:platform];
[Phobos track:@"page_click_share_channel" attributes:@{@"page_name":SafeString(weakSelf.pageName),
@"share_channel":SafeString([GMShareSDK shareChannel:platform])}];
};
}
return _shareSheet;
}
-(GMImageView *)shareImageView {
if (!_shareImageView) {
_shareImageView = [[GMImageView alloc] init];
_shareImageView.frame = CGRectMake(0, 0, MAINSCREEN_WIDTH, MAINSCREEN_HEIGHT);
_shareImageView.contentMode = UIViewContentModeScaleAspectFill;
}
return _shareImageView;
}
@end
This diff is collapsed.
This source diff could not be displayed because it is too large. You can view the blob instead.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
//
// GMFaceBaseVC.h
// Gengmei
//
// Created by 刘鹿杰 on 2019/7/25.
// Copyright © 2019 更美互动信息科技有限公司. All rights reserved.
//
#import "GMDrawDottedView.h"
@class GMFaceCommonPositionModel;
@class GMFaceCommonSubtitleModel;
@class GMFaceCommonContentModel;
@class GMTitleView;
@class ALFaceRectModel;
NS_ASSUME_NONNULL_BEGIN
@interface GMFaceBaseVC : WMBaseViewController
@property (nonatomic, strong) GMImageView *picImageView; // 当前页面图片
@property (nonatomic, strong) GMImageView *titleImageView; // 页面标题imageView
@property (nonatomic, assign) BOOL stopGCD; // 是否停用GCD, 结束当前页面动画
@property (nonatomic, strong) NSMutableArray *allViewLine; // 页面需要消失的线
#pragma mark - 录屏页面第一页 - 画线通用方法
/**
面部分析黄金三角文字展示
*/
-(void)creatFourWord:(NSArray *)triangleArray
addModel:(GMFaceCommonContentModel *)model;
/**
面部分析 画下巴线条
*/
-(void)addChinLine:(NSArray *)chinArray
descModel:(GMFaceCommonContentModel *)descModel;
/**
面部分析 画竖线加描述文字
*/
- (void)creatVorticalDescLine:(NSArray *)pModelArray
content:(GMFaceCommonContentModel *)descModel
offset:(CGFloat)offsetX;
/**
面部分析 画四条横线
*/
- (void)creatHorizontalLine:(NSMutableArray *)pointArray;
#pragma mark - 第五个页面动画 - 画线通用方法
/**
眉眼分析 - 四条虚线箭头带文字
*/
-(void)fiveViewdrawDottodlineWithEye:(NSArray<GMFaceCommonPositionModel *> *)eyeArray
eyebrow:(NSArray<GMFaceCommonPositionModel *> *)eyebroArray
modelAry:(NSArray *)modelAry;
/**
眉眼分析 - 横线和竖线
*/
- (void)fiveViewdrawlineWithEye:(NSArray<GMFaceCommonPositionModel *> *)eyeNewPoint
eyebrow:(NSArray<GMFaceCommonPositionModel *> *)eyebrowNewPoint;
#pragma mark - 第六个页面动画 - 画线通用方法
/**
第六个页面虚线箭头带文字绘画方法
*/
- (void)drawDottodLineWithPointArray:(NSArray<GMFaceCommonPositionModel *> *)pointArray
content:(GMFaceCommonContentModel *)contentModel
type:(GMLineType)lineType
place:(GMWordPlace)place;
/**
第六个页面水平线绘画方法
*/
- (void)drawSixhLine:(NSArray<GMFaceCommonPositionModel *> *)pointXArray
widthArray:(NSArray<NSNumber *> *)widthArray;
/**
第六个页面竖线方法
*/
- (void)drawSixVerticalLine:(NSArray<GMFaceCommonPositionModel *> *)pointXArray
hightArray:(NSArray<NSNumber *> *)hightArray;
#pragma mark - 公用方法
/**
创建带描述文字的竖线 文字在右侧
@param contentModel 描述文字
@param pointArray 画线的点位传两个点过来
*/
-(void)creatVerticalDottedLineWith:(GMFaceCommonContentModel *)contentModel addArray:(NSArray *)pointArray offset:(CGFloat)offset;
/**
计算两点之间的水平宽度
*/
-(CGFloat)calculateWidthWithArray:(NSArray*)array;
/**
返回中心点model
*/
-(GMFaceCommonPositionModel *)calculateCenterModelWithArray:(NSArray*)array;
/**
更新背景图片的尺寸
*/
- (void)updatePicImageViewframeP;
/**
给一个矩形框,返回一个宽和高
*/
- (CGSize)getWidthAddHightWithRect:(NSArray<GMFaceCommonPositionModel *> *)rectArray;
/**
计算中心点坐标
*/
-(NSArray *)midlePointWithModel:(ALFaceRectModel *)model;
/**
计算放大后的点位置
*/
-(NSMutableArray *)bigImagePointWithScale:(CGFloat)scale
offsetX:(CGFloat)offsetX
offsetY:(CGFloat)offsetY
poinyArray:(NSArray *)pointArray;
/**
左侧描述弹出框方法封装
*/
- (void)leftPopTitleWith:(NSMutableArray *)viewLineArray
AddSubtitle:(NSArray *)subTitle
Animation:(CGFloat)duration;
/**
添加描述文字单个小View
*/
- (GMTitleView *)addDectTitleNameWithModel:(GMFaceCommonSubtitleModel *)tempModel
viewFrame:(CGRect)frame;
/**
创建黄金三角类似的文字
*/
- (GMLabel *)creatLabelWithText:(NSString *)text
Font:(CGFloat)font
Color:(UIColor *)color
Size:(CGRect)frame;
/**
画线方法
*/
- (CAShapeLayer *)drawLineMethod:(NSArray<GMFaceCommonPositionModel *>*)positionModelArray
Color:(UIColor *)color;
/**
清除页面线条View
*/
- (void)clearFristViewLineView;
@end
NS_ASSUME_NONNULL_END
This diff is collapsed.
//
// GMFaceInfoShareViewController.h
// Gengmei
//
// Created by Locus on 2019/6/5.
// Copyright © 2019 更美互动信息科技有限公司. All rights reserved.
//
#import "GMBaseWebViewController.h"
static NSString * const cellID = @"cell";
#define ShareImageHeight (MAINSCREEN_HEIGHT - UIView.safeAreaInsetsBottom - 206 - self.navigationBar.bottom)
#define ItemMargin 20
#define btnBottomMargin - (23 + UIView.safeAreaInsetsBottom)
@interface GMFaceShareCell : GMCollectionViewCell
@property (nonatomic, strong) UIImageView *imageView;
@property (nonatomic, strong) UIImage *image;
@end
@interface GMFaceShareFlowLayout : UICollectionViewFlowLayout
@end
@class GMFaceV3Model;
@interface GMFaceInfoShareViewController : GMBaseWebViewController
@property (nonatomic, strong) GMFaceV3Model *faceModel;
@end
//
// GMFacePointViewController.h
// Gengmei
//
// Created by 刘鹿杰 on 2019/6/26.
// Copyright © 2019 更美互动信息科技有限公司. All rights reserved.
//
NS_ASSUME_NONNULL_BEGIN
@class GMFaceV3Model;
@interface GMFacePointViewController : WMBaseViewController
@property(nonatomic, assign) BOOL isGene; // 区分是不是从面孔起源过来的
- (instancetype)initWithModel:(GMFaceV3Model *)faceModel;
@end
NS_ASSUME_NONNULL_END
This diff is collapsed.
//
// GMFaceReplayResultVC.h
// Gengmei
//
// Created by 刘鹿杰 on 2019/7/26.
// Copyright © 2019 更美互动信息科技有限公司. All rights reserved.
//
NS_ASSUME_NONNULL_BEGIN
@class GMFaceV3Model;
@class GMFaceReplayModel;
@interface GMFaceReplayResultVC : WMBaseViewController
- (instancetype)initWithModel:(GMFaceV3Model *)faceModel replayModel:(GMFaceReplayModel *)replayModel;
@end
NS_ASSUME_NONNULL_END
This diff is collapsed.
//
// GMFaceReplayViewController.h
// Gengmei
//
// Created by 刘鹿杰 on 2019/7/24.
// Copyright © 2019 更美互动信息科技有限公司. All rights reserved.
//
#import "GMFaceBaseVC.h"
@class GMFaceV3Model;
@class GMFaceReplayModel;
NS_ASSUME_NONNULL_BEGIN
@interface GMFaceReplayViewController : GMFaceBaseVC
- (instancetype)initWithModel:(GMFaceV3Model *)faceModel replayModel:(GMFaceReplayModel *)replayModel;
@end
NS_ASSUME_NONNULL_END
This diff is collapsed.
//
// GMScanAnimationController.h
// Gengmei
//
// Created by 刘鹿杰 on 2019/6/19.
// Copyright © 2019 更美互动信息科技有限公司. All rights reserved.
//
NS_ASSUME_NONNULL_BEGIN
@interface GMScanAnimationController : WMBaseViewController
@property (nonatomic, strong) UIImage *image;
@end
NS_ASSUME_NONNULL_END
//
// GMScanAnimationController.m
// Gengmei
//
// Created by 刘鹿杰 on 2019/6/19.
// Copyright © 2019 更美互动信息科技有限公司. All rights reserved.
//
#import "GMScanAnimationController.h"
#import "ALFaceInfoViewModel.h"
#import "UIImage+GMExtension.h"
#import "GMFaceV3Util.h"
@interface GMScanAnimationController ()
@end
@implementation GMScanAnimationController
-(void)initController{
[super initController];
self.navigationBar.backgroundColor = UIColor.clearColor;
self.navigationBar.titleLabel.textColor = UIColor.whiteColor;
self.navigationBar.leftIcon = @"NewFaceBack";
self.navigationBar.isShowShadow = NO;
}
- (void)viewDidLoad {
[super viewDidLoad];
UIImage *newImage = [self.image normalizedImage]; // 防止iOS 13 图片自动旋转90度
GMImageView *imageView = [[GMImageView alloc] init];
imageView.contentMode = UIViewContentModeScaleAspectFill;
imageView.frame = self.view.frame;
imageView.image = newImage;
[self.view addSubview:imageView];
GMImageView *line = [[GMImageView alloc] initWithFrame:CGRectMake(0, -162, MAINSCREEN_WIDTH, 162)];
line.backgroundColor = [UIColor blueColor];
line.tag = 1111;
line.image = [UIImage imageNamed:@"icon_face_scanning_down"];
line.contentMode = UIViewContentModeScaleAspectFill;
line.backgroundColor = [UIColor clearColor];
[self.view addSubview:line];
[self addAnimation];
[GMFaceV3Util uploadOneImageToQiNiu:newImage vc:self successBlock:NULL];
}
-(void)viewWillDisappear:(BOOL)animated{
[super viewWillDisappear:animated];
[self removeAnimation];
}
// 添加扫描动画
- (void)addAnimation{
UIView *line = [self.view viewWithTag:1111];
line.hidden = NO;
CABasicAnimation *animation = [GMScanAnimationController moveYTime:2.5 fromY:[NSNumber numberWithFloat:0] toY:[NSNumber numberWithFloat:MAINSCREEN_HEIGHT] rep:OPEN_MAX];
[line.layer addAnimation:animation forKey:@"LineAnimation"];
}
// 去除扫描动画
- (void)removeAnimation{
UIView *line = [self.view viewWithTag:1111];
[line.layer removeAnimationForKey:@"LineAnimation"];
line.hidden = YES;
}
+ (CABasicAnimation *)moveYTime:(float)time fromY:(NSNumber *)fromY toY:(NSNumber *)toY rep:(int)rep{
CABasicAnimation *animationMove = [CABasicAnimation animationWithKeyPath:@"transform.translation.y"];
[animationMove setFromValue:fromY];
[animationMove setToValue:toY];
animationMove.duration = time;
animationMove.repeatCount = rep;
animationMove.fillMode = kCAFillModeForwards;
animationMove.removedOnCompletion = YES;
animationMove.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
return animationMove;
}
@end
//
// GMTestSkinAnimationWebView.h
// Gengmei
//
// Created by 刘鹿杰 on 2019/8/21.
// Copyright © 2019 更美互动信息科技有限公司. All rights reserved.
//
NS_ASSUME_NONNULL_BEGIN
@interface GMTestSkinAnimationWebView : WMBaseViewController
// 需要上传到七牛的图片
@property (nonatomic, strong) UIImage *image;
@end
NS_ASSUME_NONNULL_END
This diff is collapsed.
This diff is collapsed.
//
// GMImageView+GMFace.h
// Gengmei
//
// Created by 刘鹿杰 on 2019/6/26.
// Copyright © 2019 更美互动信息科技有限公司. All rights reserved.
//
NS_ASSUME_NONNULL_BEGIN
@interface GMImageView (GMFace)
// 给定 X 轴, 画虚 - 竖线
+ (GMImageView *)creatVerticalDottedWithX:(CGFloat)X;
// 给定 X 轴, 画实 - 竖线
+ (GMImageView *)creatVerticalPathWithX:(CGFloat)X;
// 给定 Y 轴, 画虚 - 横线
+ (GMImageView *)creatHorizontalDottedWithY:(CGFloat)Y;
// 给定 Y 轴, 画实 - 横线
+ (GMImageView *)creatHorizontalPathWithY:(CGFloat)Y;
@end
NS_ASSUME_NONNULL_END
This diff is collapsed.
//
// GMNewFaceTool.h
// Gengmei
//
// Created by 叶凤鸣 on 2019/6/19.
// Copyright © 2019 更美互动信息科技有限公司. All rights reserved.
//
typedef void(^NewPhotoCallBack)(UIImage *image);
@interface GMNewFaceTool : NSObject
+ (void)latestImage:(NewPhotoCallBack)callBack;
@end
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment