You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何使用DJI SDK(Swift)在每个航点处理拍摄的图像?

解决DJI航点任务中获取拍照图片并执行自定义逻辑的方案

我来给你梳理下在DJI Mobile SDK里实现这个需求的具体步骤,亲测可行:

一、监听航点到达事件,触发自定义方法

DJI的航点任务(DJIWaypointMission)提供了代理回调,可以精准捕获无人机到达每个航点的时机,这时候你就能调用自己的非DJIWaypointAction方法了。

首先要设置航点任务的代理:

// 假设你已经初始化了waypointMission对象
waypointMission.delegate = self;

然后实现代理方法waypointMission:didReachWaypointAtIndex:,这个方法会在无人机到达指定索引的航点时触发:

- (void)waypointMission:(DJIWaypointMission *)mission didReachWaypointAtIndex:(NSInteger)index {
    // 这里就是你执行自定义逻辑的地方
    NSLog(@"到达第%ld个航点,开始执行自定义操作", index);
    [self fetchLatestImageFromSDCard]; // 调用你自己的获取图片方法
}

二、从无人机SD卡获取照片并转为UIImage

要获取SD卡中的照片,核心是用DJIMediaManager来操作媒体文件:

  1. 先获取飞行器的MediaManager实例:
DJIAircraft *aircraft = (DJIAircraft *)[DJISDKManager product];
if (!aircraft || !aircraft.mediaManager) {
    NSLog(@"无法获取MediaManager,请检查飞行器连接状态");
    return;
}
DJIMediaManager *mediaManager = aircraft.mediaManager;
  1. 获取SD卡中的媒体列表,筛选出最新的拍照文件:
[mediaManager fetchMediaListWithCompletion:^(NSArray<DJIMedia *> * _Nullable mediaList, NSError * _Nullable error) {
    if (error) {
        NSLog(@"获取媒体列表失败:%@", error.localizedDescription);
        return;
    }
    // 筛选出照片(排除视频、缩略图等),并按创建时间倒序排列,取最新的一张
    NSArray<DJIMedia *> *photoMediaList = [mediaList filteredArrayUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(DJIMedia *media, NSDictionary *bindings) {
        return media.mediaType == DJIMediaTypePhoto;
    }]];
    // 按创建时间排序
    NSArray<DJIMedia *> *sortedPhotos = [photoMediaList sortedArrayUsingComparator:^NSComparisonResult(DJIMedia *obj1, DJIMedia *obj2) {
        return [obj2.createDate compare:obj1.createDate];
    }];
    if (sortedPhotos.count > 0) {
        DJIMedia *latestPhoto = sortedPhotos.firstObject;
        [self downloadMedia:latestPhoto];
    } else {
        NSLog(@"SD卡中没有照片");
    }
}];
  1. 下载选中的媒体文件并转为UIImage:
- (void)downloadMedia:(DJIMedia *)media {
    DJIAircraft *aircraft = (DJIAircraft *)[DJISDKManager product];
    if (!aircraft || !aircraft.mediaManager) return;
    
    // 下载原尺寸图片
    [aircraft.mediaManager downloadMedia:media withDestinationPath:[self getLocalSavePath] progress:^(NSInteger bytesWritten, NSInteger totalBytesWritten, NSInteger totalBytesExpectedToWrite) {
        // 可以在这里更新下载进度
        NSLog(@"下载进度:%.2f%%", (float)totalBytesWritten / totalBytesExpectedToWrite * 100);
    } completion:^(NSURL * _Nullable filePath, NSError * _Nullable error) {
        if (error) {
            NSLog(@"下载失败:%@", error.localizedDescription);
            return;
        }
        // 转成UIImage,注意要在主线程更新UI
        dispatch_async(dispatch_get_main_queue(), ^{
            UIImage *image = [UIImage imageWithContentsOfFile:filePath.path];
            if (image) {
                // 这里拿到了UIImage,你可以进行后续处理(比如显示、上传等)
                NSLog(@"成功获取到图片,尺寸:%.fx%.f", image.size.width, image.size.height);
                [self processCapturedImage:image]; // 调用你的图片处理方法
            } else {
                NSLog(@"图片转码失败");
            }
        });
    }];
}

// 生成本地保存路径的辅助方法
- (NSString *)getLocalSavePath {
    NSString *documentsDir = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).firstObject;
    return [documentsDir stringByAppendingPathComponent:@"DJIPhoto.jpg"];
}

三、注意事项

  • 确保App已经获取了文件读写权限相册访问权限(如果需要保存到相册的话);
  • 操作MediaManager时,要保证无人机和App处于稳定的连接状态;
  • 下载媒体文件是异步操作,记得处理回调中的错误情况;
  • 如果需要对应每个航点的照片,可以在航点到达时记录时间戳,后续筛选媒体文件时匹配时间范围,避免获取到其他航点的照片。

内容的提问来源于stack exchange,提问作者Vhan

火山引擎 最新活动