Files
yinmeng-ios/xplan-ios/Main/ModuleKit/FaceView/XPFaceParser/FaceImageTool.m
2022-03-10 18:55:18 +08:00

443 lines
15 KiB
Objective-C

//
// FaceImageTool.m
// BberryCore
//
// Created by 何卫明 on 2017/12/8.
// Copyright © 2017年 chenran. All rights reserved.
//
#import "FaceImageTool.h"
//#import "FaceCoreClient.h"
#import "GCDHelper.h"
#import <ReactiveObjC/ReactiveObjC.h>
#import "XPFaceParser.h"
#define SPACES 15
@interface FaceImageTool () <CAAnimationDelegate>
@property (nonatomic, copy) IsFinish isFinish;
@end
@implementation FaceImageTool {
dispatch_queue_t faceQueue;
}
- (instancetype)init
{
self = [super init];
if (self) {
faceQueue = dispatch_queue_create("com.yy.face.xcface.creatFace", DISPATCH_QUEUE_SERIAL);
}
return self;
}
+ (instancetype)shareFaceImageTool
{
static dispatch_once_t onceToken = 0;
static id instance;
dispatch_once(&onceToken, ^{
instance = [[self alloc] init];
});
return instance;
}
#pragma mark - CAAnimationDelegate
- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag{
@weakify(self);
dispatch_main_sync_safe(^{
@strongify(self);
if (self.isFinish) {
self.isFinish(flag);
}
});
}
- (void)queryImage:(FaceReceiveInfo *)receiveInfo
imageView:(UIImageView *)imageView
dragon:(BOOL)dragon
needAniomation:(BOOL)animation
success:(void (^)(FaceReceiveInfo *info,UIImage *lastImage))success
failure:(void (^)(NSError *))failure {
__block CGSize size = imageView.frame.size;
UIImage * result;
if (receiveInfo.resultIndexes.count > 0) {
if (dragon) {
result = [self dragoncombineImageInOne:receiveInfo size:size];
}else {
result = [self combineImageInOne:receiveInfo size:size];
}
receiveInfo.resultImage = result;
}
dispatch_main_sync_safe(^{
success(receiveInfo,result);
if(animation){
[self addAnimateInImageView:imageView receiveInfo:receiveInfo];
}
});
}
- (void)queryImage:(FaceReceiveInfo *)receiveInfo
imageView:(UIImageView *)imageView
dragon:(BOOL)dragon
needAniomation:(BOOL)animation
success:(void (^)(FaceReceiveInfo *info,UIImage *lastImage))success
failure:(void (^)(NSError *))failure
isFinish:(void (^)(BOOL isFinish))isFinish{
self.isFinish = isFinish;
[self queryImage:receiveInfo imageView:imageView dragon:dragon needAniomation:animation success:success failure:failure];
}
- (void)addAnimateInImageView:(UIImageView *)imageView receiveInfo:(FaceReceiveInfo *)receiveInfo {
FaceConfigInfo *configInfo = [[XPFaceParser shareParser] findFaceInfoById:receiveInfo.faceId];
if (receiveInfo.resultIndexes.count > 0) {
/*==================== 动画数组 ================= */
//创建CAKeyframeAnimation
CAKeyframeAnimation *animation = [CAKeyframeAnimation animationWithKeyPath:@"contents"];
animation.duration = configInfo.animDuration / 1000.0;
animation.delegate = self;
animation.repeatCount = configInfo.animRepeatCount;
animation.removedOnCompletion = YES;
animation.calculationMode = kCAAnimationDiscrete;
//存放图片的数组
NSMutableArray *faceArray = [NSMutableArray array];
for (int i = (short)configInfo.animStartPos; i <= (short)configInfo.animEndPos; i ++) {
UIImage *image = [[XPFaceParser shareParser] findFaceImageByConfig:configInfo index:i];
if (image) {
CGImageRef cgimg = image.CGImage;
[faceArray addObject:(__bridge UIImage *)cgimg];
}else {
break;
}
}
if (faceArray.count > 0) {
animation.values = faceArray;
}else {
return;
}
/*==================== 结果数组 ================= */
CAKeyframeAnimation *resultAnimation = [CAKeyframeAnimation animationWithKeyPath:@"contents"];
resultAnimation.duration = 3;
resultAnimation.delegate = self;
resultAnimation.beginTime = configInfo.animRepeatCount * configInfo.animDuration / 1000.0;
//存放图片的数组
NSMutableArray *resultArray = [NSMutableArray array];
if (receiveInfo.resultImage) {
[resultArray addObject:(__bridge UIImage *)receiveInfo.resultImage.CGImage];
}else {
return;
}
if (resultArray.count > 0) {
resultAnimation.values = resultArray;
}else {
return;
}
resultAnimation.removedOnCompletion = YES;
CAAnimationGroup *group = [CAAnimationGroup animation];
group.animations = @[animation,resultAnimation];
group.duration = 3 + (configInfo.animDuration / 1000.0) * configInfo.animRepeatCount;
group.delegate = self;
[imageView.layer addAnimation:group forKey:nil];
// [imageView setImage:receiveInfo.resultImage];
} else {
/*==================== 动画数组 ================= */
//创建CAKeyframeAnimation
CAKeyframeAnimation *animation = [CAKeyframeAnimation animationWithKeyPath:@"contents"];
animation.duration = configInfo.animDuration / 1000.0;
animation.delegate = self;
animation.repeatCount = configInfo.animRepeatCount;
animation.removedOnCompletion = YES;
animation.calculationMode = kCAAnimationDiscrete;
//存放图片的数组
NSMutableArray *faceArray = [NSMutableArray array];
for (int i = (short)configInfo.animStartPos; i <= (short)configInfo.animEndPos; i ++) {
UIImage *image = [[XPFaceParser shareParser] findFaceImageByConfig:configInfo index:i];
if (image) {
CGImageRef cgimg = image.CGImage;
[faceArray addObject:(__bridge UIImage *)cgimg];
}else {
break;
}
}
if (faceArray.count > 0) {
animation.values = faceArray;
[imageView.layer removeAnimationForKey:@"face"];
[imageView.layer addAnimation:animation forKey:@"face"];
}else {
return;
}
}
}
//- (void)saveImageWithArr:(NSMutableArray<FaceReceiveInfo *> *)faceRecieveInfos
// imageView:(UIImageView *)imageView
// success:(void (^)(NSMutableArray<FaceReceiveInfo *> *))success
// failure:(void (^)(NSError *))failure{
// __block CGSize size = imageView.frame.size;
// @weakify(self);
// dispatch_async(faceQueue, ^{
// @strongify(self);
// for (FaceReceiveInfo *item in faceRecieveInfos) {
// if (item.resultIndexes.count > 0) { //运气表情
//
// __block UIImage * result = [self combineImageInOne:item size:size];
// item.resultImage = result;
// }else { //普通表情
//// FaceConfigInfo *configInfo = [GetCore(FaceCore)findFaceInfoById:item.faceId];
//// UIImage *singleImage = [GetCore(FaceCore)findFaceImageById:faceInfo.faceId index:index];
//// item.resultImage =
// }
// }
// dispatch_main_sync_safe(^{
// success(faceRecieveInfos);
// });
// });
//
//}
- (UIImage *)combineImageInOne:(FaceReceiveInfo *)faceInfo size:(CGSize)size {
UIImage *result;
NSInteger faceCount = faceInfo.resultIndexes.count > 9 ? 9 : faceInfo.resultIndexes.count;
CGFloat x = 0;
CGFloat y = 0;
CGFloat width = 0.0;
CGFloat height;
CGFloat whBit = 174.0 / 128.0;
switch (faceInfo.resultIndexes.count) {
case 1:
{
width = size.width;
height = width / whBit;
}
break;
case 2:
case 3:
case 4:
{
width = size.width / 2;
height = width / whBit;
// height = size.height / 2;
// height =
}
break;
case 5:
case 6:
case 7:
case 8:
case 9:
{
width = size.width / 3;
height = width / whBit;
}
break;
default:
width = 0;
height = 0;
break;
}
CGFloat spaceX3 = 0; //三张图时的X间距
CGFloat spaceX2 = (size.width - width * 2) / 2; //两张图时的X边距
CGFloat spaceX1 = (size.width - width) / 2; //一张图时的X边距
CGFloat spaceY3 = 0; //三张图时的Y间距
CGFloat spaceY2 = (size.height - height * 2) / 2; //两张图时的Y间距
CGFloat spaceY1 = (size.height - height) / 2; //一张图时的Y间距
y = faceCount > 6 ? spaceY3 : (faceCount >= 3 ? spaceY2 : spaceY1);
x = faceCount % 3 == 0 && faceCount > 3 ? spaceX3 : (faceCount % 3 == 2 ? spaceX2 : spaceX1);
UIGraphicsBeginImageContextWithOptions(size, NO, [UIScreen mainScreen].scale);
for (int i = 0; i < faceCount; i++) {
NSInteger index = [faceInfo.resultIndexes[i] integerValue];
FaceConfigInfo *configInfo = [[XPFaceParser shareParser] findFaceInfoById:faceInfo.faceId];
UIImage *singleImage = [[XPFaceParser shareParser] findFaceImageById:faceInfo.faceId index:index];
if (faceCount == 1) { //只有一张图片的时候直接返回不做处理
return singleImage;
break;
}
if (configInfo.displayType == XCFaceDisplayTypeFlow) {
[singleImage drawInRect:CGRectMake(x, y, width, height)];
// x = width * (i % 3);
if (i % 3 == 0) { // 换行
y += (height + spaceY3);
x = spaceX3;
}
else if (i == 2 && faceCount == 3) { // 换行,只有三个时
y += (height + spaceY3);
x = spaceX2;
}
else {
x += (width + spaceX3);
}
// y =
}else if (configInfo.displayType == XCFaceDisplayTypeOverLay) {
CGFloat whBit = singleImage.size.width / singleImage.size.height;
width = size.width - (faceInfo.resultIndexes.count - 1) * SPACES;
height = width / whBit;
x = 0 + i * SPACES;
y = size.height / 2 - height / 2;
[singleImage drawInRect:CGRectMake(x, y, width, height)];
}
}
result = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return result;
}
//龙珠处理
- (UIImage *)dragoncombineImageInOne:(FaceReceiveInfo *)faceInfo size:(CGSize)size {
UIImage *result;
NSInteger faceCount = faceInfo.resultIndexes.count > 9 ? 9 : faceInfo.resultIndexes.count;
CGFloat x = 0;
CGFloat y = 0;
CGFloat width = 0.0;
CGFloat height;
// CGFloat whBit = 74 / 106.0;
CGFloat whBit = 1;
switch (faceInfo.resultIndexes.count) {
case 1:
{
width = size.width;
height = width / whBit;
}
break;
case 2:
case 3:
case 4:
{
width = size.width / 2;
height = width / whBit;
}
break;
case 5:
case 6:
case 7:
case 8:
case 9:
{
width = size.width / 3;
height = width / whBit;
}
break;
default:
width = 0;
height = 0;
break;
}
CGFloat spaceX3 = 0; //三张图时的X间距
CGFloat spaceX2 = (size.width - width * 2) / 2; //两张图时的X边距
CGFloat spaceX1 = (size.width - width) / 2; //一张图时的X边距
CGFloat spaceY3 = 0; //三张图时的Y间距
CGFloat spaceY2 = (size.height - height * 2) / 2; //两张图时的Y间距
CGFloat spaceY1 = (size.height - height) / 2; //一张图时的Y间距
y = faceCount > 6 ? spaceY3 : (faceCount >= 3 ? spaceY2 : spaceY1);
x = faceCount % 3 == 0 && faceCount > 3 ? spaceX3 : (faceCount % 3 == 2 ? spaceX2 : spaceX1);
UIGraphicsBeginImageContextWithOptions(size, NO, [UIScreen mainScreen].scale);
FaceConfigInfo *configInfo = [[XPFaceParser shareParser] findFaceInfoById:faceInfo.faceId];
if (configInfo.displayType == XCFaceDisplayTypeOnlyOneLine) {
UIImage *singleImage = [[XPFaceParser shareParser] findFaceImageById:faceInfo.faceId index:configInfo.animStartPos];
[singleImage drawInRect:CGRectMake(0, 0, size.width, size.height)];
}
for (int i = 0; i < faceCount; i++) {
NSInteger index = [faceInfo.resultIndexes[i] integerValue];
// FaceConfigInfo *configInfo = [GetCore(FaceCore)findFaceInfoById:faceInfo.faceId];
UIImage *singleImage = [[XPFaceParser shareParser] findFaceImageById:faceInfo.faceId index:index];
if (faceCount == 1) { //只有一张图片的时候直接返回不做处理
return singleImage;
break;
}
if (configInfo.displayType == XCFaceDisplayTypeFlow) {
[singleImage drawInRect:CGRectMake(x, y, width, height)];
if (i % 3 == 0) { // 换行
y += (height + spaceY3);
x = spaceX3;
}
else if (i == 2 && faceCount == 3) { // 换行,只有三个时
y += (height + spaceY3);
x = spaceX2;
}
else {
x += (width + spaceX3);
}
}else if (configInfo.displayType == XCFaceDisplayTypeOverLay) {
CGFloat whBit = singleImage.size.width / singleImage.size.height;
width = size.width - (faceInfo.resultIndexes.count - 1) * SPACES;
height = width / whBit;
x = 0 + i * SPACES;
y = size.height / 2 - height / 2;
[singleImage drawInRect:CGRectMake(x, y, width, height)];
}else if (configInfo.displayType == XCFaceDisplayTypeOnlyOneLine) {
CGFloat whBit = singleImage.size.width / singleImage.size.height;
width = (size.width-SPACES*2)/faceCount;
height = width / whBit;
x = width*i+SPACES;
y = size.height / 2 - height / 2;
[singleImage drawInRect:CGRectMake(x, y, width, height)];
}
}
result = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return result;
}
@end