iOS人脸识别
//
//? ViewController.m
//? 02-人臉識別
//
//? Created by Romeo on 15/9/25.
//? Copyright ? 2015年 itheima. All rights reserved.
//
?
#import "ViewController.h"
#import "FaceppAPI.h"
#import "UIView+AutoLayout.h"
?
@interface ViewController ()<UINavigationControllerDelegate, UIImagePickerControllerDelegate>
?
@property (weak, nonatomic) IBOutlet UIImageView *imageVIew;
?
@end
?
@implementation ViewController
?
- (void)viewDidLoad {
? ? [super viewDidLoad];
? ? // Do any additional setup after loading the view, typically from a nib.
}
?
/**
?UIImagePickerControllerSourceTypePhotoLibrary,? ? ? 照片庫
?UIImagePickerControllerSourceTypeCamera,? ? ? ? ? ? 相機
?UIImagePickerControllerSourceTypeSavedPhotosAlbum ? 相冊
?*/
?
#pragma mark 相冊
?
- (IBAction)selectPhotoClick:(id)sender {
? ? //1. 首先判斷是否可用
? ? if (![UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypePhotoLibrary]) {
? ? ? ? return;
? ? }
?? ?
? ? //2. 創建選擇控制器
? ? UIImagePickerController *picker = [UIImagePickerController new];
?? ?
? ? //3. 設置類型
? ? picker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
?? ?
? ? //4. 設置代理
? ? picker.delegate = self;
?? ?
? ? //5. 彈出
? ? [self presentViewController:picker animated:YES completion:nil];
}
?
#pragma mark 相機
?
- (IBAction)selectCameClick:(id)sender {
?? ?
? ? //1. 首先判斷是否可用
? ? if (![UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]) {
? ? ? ? return;
? ? }
?? ?
? ? //2. 創建選擇控制器
? ? UIImagePickerController *picker = [UIImagePickerController new];
?? ?
? ? //3. 設置類型
? ? picker.sourceType = UIImagePickerControllerSourceTypeCamera;
?? ?
? ? //4. 設置代理
? ? picker.delegate = self;
?? ?
? ? //5. 彈出
? ? [self presentViewController:picker animated:YES completion:nil];
}
?
#pragma mark Picker代理方法
//點擊照片的時候調用
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary<NSString *,id> *)info
{
? ? //1. 獲取選擇的圖像
? ? UIImage *image = info[UIImagePickerControllerOriginalImage];
?? ?
? ? //orientation 0? --> 在做人臉識別, 一定要方向為0
?? ?
? ? //2. 校正方向
? ? image = [self fixOrientation:image];
?? ?
? ? //3. 開始檢測
? ? NSData *data = UIImageJPEGRepresentation(image, 0.5);
//? ? UIImagePNGRepresentation(<#UIImage * _Nonnull image#>)
?? ?
? ? //detection/detect 檢測一張照片中的人臉信息(臉部位置、年齡、種族、性別等等)
? ? FaceppResult *result = [[FaceppAPI detection] detectWithURL:nil orImageData:data];
?? ?
? ? //4. 獲取性別,年齡
?? ?
? ? NSDictionary *attributeDict = result.content[@"face"][0][@"attribute"];
? ? NSString *ageValue = attributeDict[@"age"][@"value"];
? ? NSString *sexValue = [attributeDict[@"gender"][@"value"] isEqualToString:@"Male"] ? @"男性" : @"女性";
?? ?
? ? //5. 獲取臉部位置 (比例值)
? ? NSDictionary *positionDict = result.content[@"face"][0][@"position"];
?? ?
? ? CGFloat h = [positionDict[@"height"] floatValue];
? ? CGFloat w = [positionDict[@"width"] floatValue];
? ? CGFloat x = [positionDict[@"center"][@"x"] floatValue] - w * 0.5;
? ? CGFloat y = [positionDict[@"center"][@"y"] floatValue] - h * 0.5;
?? ?
? ? //6. 畫圖--> 畫臉到 image 上
?? ?
? ? //6.1 開啟圖像圖形上下文
? ? UIGraphicsBeginImageContextWithOptions( image.size, NO, 0);
?? ?
? ? //6.2 將原圖先繪制到底部, 從(0, 0)點開始繪制
? ? [image drawAtPoint:CGPointZero];
?? ?
? ? //6.3 畫素材圖像到圖形上下文中
? ? UIImage *aImage = [UIImage imageNamed:@"cang"];
?? ?
? ? // 根據原圖的大小比例來計算自己的位置
? ? CGFloat imageW = image.size.width;
? ? CGFloat imageH = image.size.height;
? ? [aImage drawInRect:CGRectMake(x * 0.01 * imageW , y * 0.01 * imageH, w * 0.01 * imageW, h * 0.01 * imageH)];
?? ?
? ? // 320 ? ? 50% ? ? 160
? ? //50 * 0.01 * 320 ? = 160
?? ?
? ? //6.4 合成新的圖像
? ? UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
?? ?
? ? //6.5 關閉圖像上下文
? ? UIGraphicsEndImageContext();
?? ?
? ? //7. 在控制器顯示
?? ?
? ? //刪除原有約束,然后重新添加
?? ?
? ? // 刪除原有約束
? ? [self.imageVIew autoRemoveConstraintsAffectingView];
?? ?
? ? // 設置居中
? ? [self.imageVIew autoCenterInSuperview];
?? ?
? ? // 設置寬高 --> 需要根據圖片的比例來確定
? ? //960 * 1080
?? ?
? ? // 假如我們需要寬度: 屏幕總寬度
?? ?
? ? // iPhone5 : 320
? ? // iPhone6 : 375
? ? CGFloat scale = newImage.size.width / [UIScreen mainScreen].bounds.size.width;
?? ?
?? ?
? ? //Dimension : 尺寸 --> 寬高
? ? [self.imageVIew autoSetDimension: ALDimensionWidth toSize:newImage.size.width / scale];
? ? [self.imageVIew autoSetDimension:ALDimensionHeight toSize:newImage.size.height / scale];
?? ?
? ? self.imageVIew.image = newImage;
?? ?
? ? //8. 實現了代理方法一定要取消
? ? [picker dismissViewControllerAnimated:YES completion:nil];
}
?
?
#pragma mark 方向校正
/**
?1. 先將頭部朝上
?2. 將鏡像反轉
?3. 重新合成輸出
?*/
?
- (UIImage*)fixOrientation:(UIImage*)aImage
{
?? ?
? ? // No-op if the orientation is already correct
? ? if (aImage.imageOrientation == UIImageOrientationUp)
? ? ? ? return aImage;
?? ?
? ? // We need to calculate the proper transformation to make the image upright.
? ? // We do it in 2 steps: Rotate if Left/Right/Down, and then flip if Mirrored.
? ? CGAffineTransform transform = CGAffineTransformIdentity;
?? ?
? ? switch (aImage.imageOrientation) {
? ? ? ? case UIImageOrientationDown:
? ? ? ? case UIImageOrientationDownMirrored:
? ? ? ? ? ? transform = CGAffineTransformTranslate(transform, aImage.size.width, aImage.size.height);
? ? ? ? ? ? transform = CGAffineTransformRotate(transform, M_PI);
? ? ? ? ? ? break;
?? ? ? ? ? ?
? ? ? ? case UIImageOrientationLeft:
? ? ? ? case UIImageOrientationLeftMirrored:
? ? ? ? ? ? transform = CGAffineTransformTranslate(transform, aImage.size.width, 0);
? ? ? ? ? ? transform = CGAffineTransformRotate(transform, M_PI_2);
? ? ? ? ? ? break;
?? ? ? ? ? ?
? ? ? ? case UIImageOrientationRight:
? ? ? ? case UIImageOrientationRightMirrored:
? ? ? ? ? ? transform = CGAffineTransformTranslate(transform, 0, aImage.size.height);
? ? ? ? ? ? transform = CGAffineTransformRotate(transform, -M_PI_2);
? ? ? ? ? ? break;
? ? ? ? default:
? ? ? ? ? ? break;
? ? }
?? ?
? ? switch (aImage.imageOrientation) {
? ? ? ? case UIImageOrientationUpMirrored:
? ? ? ? case UIImageOrientationDownMirrored:
? ? ? ? ? ? transform = CGAffineTransformTranslate(transform, aImage.size.width, 0);
? ? ? ? ? ? transform = CGAffineTransformScale(transform, -1, 1);
? ? ? ? ? ? break;
?? ? ? ? ? ?
? ? ? ? case UIImageOrientationLeftMirrored:
? ? ? ? case UIImageOrientationRightMirrored:
? ? ? ? ? ? transform = CGAffineTransformTranslate(transform, aImage.size.height, 0);
? ? ? ? ? ? transform = CGAffineTransformScale(transform, -1, 1);
? ? ? ? ? ? break;
? ? ? ? default:
? ? ? ? ? ? break;
? ? }
?? ?
? ? // Now we draw the underlying CGImage into a new context, applying the transform
? ? // calculated above.
? ? CGContextRef ctx = CGBitmapContextCreate(NULL, aImage.size.width, aImage.size.height,
?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? CGImageGetBitsPerComponent(aImage.CGImage), 0,
?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? CGImageGetColorSpace(aImage.CGImage),
?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? CGImageGetBitmapInfo(aImage.CGImage));
? ? CGContextConcatCTM(ctx, transform);
? ? switch (aImage.imageOrientation) {
? ? ? ? case UIImageOrientationLeft:
? ? ? ? case UIImageOrientationLeftMirrored:
? ? ? ? case UIImageOrientationRight:
? ? ? ? case UIImageOrientationRightMirrored:
? ? ? ? ? ? CGContextDrawImage(ctx, CGRectMake(0, 0, aImage.size.height, aImage.size.width), aImage.CGImage);
? ? ? ? ? ? break;
?? ? ? ? ? ?
? ? ? ? default:
? ? ? ? ? ? CGContextDrawImage(ctx, CGRectMake(0, 0, aImage.size.width, aImage.size.height), aImage.CGImage);
? ? ? ? ? ? break;
? ? }
?? ?
? ? // And now we just create a new UIImage from the drawing context
? ? CGImageRef cgimg = CGBitmapContextCreateImage(ctx);
? ? UIImage* img = [UIImage imageWithCGImage:cgimg];
? ? CGContextRelease(ctx);
? ? CGImageRelease(cgimg);
? ? return img;
}
?
@end
?
轉載于:https://www.cnblogs.com/cfl911014/p/5276361.html
總結
- 上一篇: iOS中Block的基础用法
- 下一篇: C#微信公众号开发 -- (七)自定义菜