ARKit的实现以及延伸

为什么选EasyAR

AR的广泛应用

AR(Augmented Reality)即增强现实,是一种实时地计算摄影机影像的位置及角度并加上相应图像、视频、3D模型的技术,这种技术的目标是在屏幕上把虚拟世界套在现实世界并进行互动。

近几年AR的应用越来越广泛,样式繁多的AR应用场景给app的效果提供了更多的可能,AR的互动性体验也逐渐被广泛接受,成为用户十分喜爱并乐于尝试的功能。

主流SDK

  • ARToolKit

  • Vuforia

  • ARKit

  • ARCore

  • HiAR

  • EasyAR

EasyAR的优势

1. 较完善的中文文档

1. 云识别

使用SDK创建EasyAR工程

资源下载与文档查看

开发者可以登录EasyAR官网查看EasyAR的服务和相关文档;

通过资料下载可以下载相关SDK(含Unity或不含Unity)和示例程序。

注册Licence Key添加所需SDK

首先注册Licence Key,添加SDK到工程中。

所需添加其他库如下图:

添加库

运行示例程序

从官网下载的示例程序必须运行在真机上,且需要将Enable Bitcode设置为NO。

设置Bitcode

实现扫描实物播放对应视频功能

该功能基于模式识别和AR技术,官方示例程序中的HelloARVideo已经实现了根据本地图片识别播放对应视频的功能。在此基础上,本博客旨在灵活运用EasyAR的相关功能,按类别将所要识别的目标图片储存于云端,用户可按需主动获取相关资源文件,在获取目标图片的基础下实现识别并在线播放对应视频的功能。

code

1. 从服务端下载目标图片压缩包并解压

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74

- (void)downloadFileWithURL:(NSURL *)URL {

NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];

AFURLSessionManager *mannager = [[AFURLSessionManager alloc] initWithSessionConfiguration:configuration];

NSURLRequest *request = [NSURLRequest requestWithURL:URL];

MBProgressHUD *hud = [MBProgressHUD showHUDAddedTo:self.view animated:YES];

hud.mode = MBProgressHUDModeAnnularDeterminate;

hud.label.text = @"正在更新资源包…";

_downloadTask = [mannager downloadTaskWithRequest:request progress:^(NSProgress * _Nonnull downloadProgress) {

if (downloadProgress) {

CGFloat currentProgress = (CGFloat)downloadProgress.completedUnitCount / downloadProgress.totalUnitCount;

dispatch_async(dispatch_get_main_queue(), ^{

hud.progress = currentProgress;

hud.label.text = [NSString stringWithFormat:@"正在更新资源包:%.0f%%\n",currentProgress * 100];

});

NSLog(@"%@",[NSString stringWithFormat:@"当前进度为:%.2f%%",currentProgress * 100]);

}

} destination:^NSURL * _Nonnull(NSURL * _Nonnull targetPath, NSURLResponse * _Nonnull response) {

// 将zip文件下载保存到沙盒的Cache路径下

NSString *cachePath = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject];

NSString *path = [cachePath stringByAppendingString:response.suggestedFilename];

return [NSURL fileURLWithPath:path];

} completionHandler:^(NSURLResponse * _Nonnull response, NSURL * _Nullable filePath, NSError * _Nullable error) {

[hud hideAnimated:YES];

NSString *imgFilePath = [filePath path];

NSFileManager *fileManger = [NSFileManager defaultManager];

NSString *imgaesPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject];

// remove

[fileManger removeItemAtPath:imgaesPath error:nil];

[fileManger createDirectoryAtPath:imgaesPath withIntermediateDirectories:YES attributes:nil error:nil];

// unzip 将zip文件解压并保存到Document下

[SSZipArchive unzipFileAtPath:imgFilePath toDestination:imgaesPath];

// scan

ARViewController *arVC = [[ARViewController alloc] init];

[self presentViewController:arVC animated:YES completion:nil];

}];

[_downloadTask resume];

}

2. 加载targets

helloarinitialize方法中使用loadFromImage方法加载目标图片。

1
2
3
4
5
6

for (int i = 0; i < targetCount; i++) {

loadFromImage(tracker, imageName,i);

}

在中loadFromImage修改json生存方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36

NSString *documentPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject];

easyar_ImageTarget * target = [easyar_ImageTarget create];

NSString * absolutePath = [documentPath stringByAppendingString:[NSString stringWithFormat:@"/targets/%@",name]];

NSString *uid = [NSString stringWithFormat:@"%d",index];

NSString * jstr = [@[@"{\n"

" \"images\" :\n"

" [\n"

" {\n"

" \"name\" : \"", name, @"\",\n"

" \"image\" : \"", absolutePath, @"\",\n"

" \"uid\" : \"", uid, @"\"\n"

" }\n"

" ]\n"

"}"] componentsJoinedByString:@""];

[target setup:jstr storageType:(easyar_StorageType_Assets | easyar_StorageType_Json) name:@""];

[tracker loadTarget:target callback:^(easyar_Target * target, bool status) {

NSLog(@"load target (%d): %@ (%d)", status, [target name], [target runtimeID]);

}];

3. 根据目标图片uid指定特定视频链接

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58

if (status == easyar_TargetStatus_Tracked) { // 追踪到目标

int runtimeID = [target runtimeID];

if (active_target != 0 && active_target != runtimeID) {

[video onLost];

video = nil;

tracked_target = 0;

active_target = 0;

}

if (tracked_target == 0) {

if (video == nil && [video_renderers count] > 0) {

NSString * target_uid = [target uid];

NSArray *videoArr = @[@"http://img.dpm.org.cn/Uploads/File/2018/04/19/haitang.mp4",

@"http://img.dpm.org.cn/Uploads/File/2017/11/27/wanhean.mp4",

@"http://img.dpm.org.cn/Uploads/File/2017/10/30/fxyxd.mp4",

@"http://img.dpm.org.cn/Uploads/File/2017/05/03/u5909ad6a125e1.mp4",

@"http://img.dpm.org.cn/Uploads/File/2017/05/03/u5909ad888a6c0.mp4",

@"http://img.dpm.org.cn/Uploads/File/2017/05/03/repair_new.mp4",

@"http://img.dpm.org.cn/Uploads/File/2017/03/22/u58d21fa8ed99a.mp4",

@"http://img.dpm.org.cn/Uploads/File/2017/03/22/u58d21f1215622.mp4",

@"http://img.dpm.org.cn/Uploads/File/2017/03/22/u58d21f012d948.mp4",

@"http://img.dpm.org.cn/Uploads/File/2017/03/22/u58d21fa8ed99a.mp4",

@"http://img.dpm.org.cn/Uploads/File/2017/03/22/u58d21f1215622.mp4",

@"http://img.dpm.org.cn/Uploads/File/2017/03/22/u58d21f012d948.mp4"];

if ([[video_renderers objectAtIndex:[target_uid integerValue]] texid] != 0) {

NSString *urlStr = [videoArr objectAtIndex:[target_uid integerValue]];

video = [[ARVideo alloc] init];

[video openStreamingVideo:urlStr texid:[[video_renderers objectAtIndex:[target_uid integerValue]] texid]];

current_video_renderer = [video_renderers objectAtIndex:[target_uid integerValue]];

}

Demo已上传至GitHub

BTW: 由于EasyAR的文档不尽完善,且对iOS的支持不是很好,可尝试苹果官方系统库ARKit的实现ARKit应用之识别图像播放视频

1
/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk/usr/lib/