#import "DCUniModule.h"
#import <ADY_IMG_SDK/ADY_IMG_SDK.h>
#import <ADY_IMG_SDK/yolo_api.h>
#import <UIKit/UIKit.h>
@interface ADYIMGPlugin : DCUniModule
@end
@implementation ADYIMGPlugin
#pragma mark - 初始化模型
UNI_EXPORT_METHOD(@selector(loadModel:callback:))
- (void)loadModel:(NSDictionary *)options callback:(UniModuleKeepAliveCallback)callback {
NSString *paramPath = options[@"paramPath"];
NSString *binPath = options[@"binPath"];
if (!paramPath || !binPath) {
callback(@{@"code": @400, @"message": @"参数路径不能为空"}, NO);
return;
}
// 转换为C字符串
const char *param_c = [paramPath UTF8String];
const char *bin_c = [binPath UTF8String];
// 调用SDK初始化
bool success = yolo_load_model(param_c, bin_c);
if (success) {
callback(@{@"code": @200, @"message": @"模型加载成功"}, NO);
} else {
callback(@{@"code": @500, @"message": @"模型加载失败"}, NO);
}
}
#pragma mark - 目标检测
UNI_EXPORT_METHOD(@selector(detect:callback:))
- (void)detect:(NSDictionary *)options callback:(UniModuleKeepAliveCallback)callback {
// 获取图片数据
NSString *base64Image = options[@"image"];
NSNumber *maxObjects = options[@"maxObjects"] ?: @100;
if (!base64Image) {
callback(@{@"code": @400, @"message": @"图片数据不能为空"}, NO);
return;
}
// 将base64转为UIImage
NSData *imageData = [[NSData alloc] initWithBase64EncodedString:base64Image options:0];
UIImage *image = [UIImage imageWithData:imageData];
if (!image) {
callback(@{@"code": @400, @"message": @"图片格式错误"}, NO);
return;
}
// 转换为RGBA数据
CGImageRef cgImage = image.CGImage;
size_t width = CGImageGetWidth(cgImage);
size_t height = CGImageGetHeight(cgImage);
// 创建颜色空间和上下文
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGContextRef context = CGBitmapContextCreate(NULL,
width,
height,
8,
width * 4,
colorSpace,
kCGImageAlphaPremultipliedLast | kCGBitmapByteOrderDefault);
CGContextDrawImage(context, CGRectMake(0, 0, width, height), cgImage);
// 获取RGBA数据
unsigned char *rgbaData = (unsigned char *)CGBitmapContextGetData(context);
// 准备输出数组
int maxObjectsInt = [maxObjects intValue];
int outPoints[maxObjectsInt * 4]; // 每个对象4个点(x,y)
// 调用检测接口
int detectedCount = yolo_detect(rgbaData, (int)width, (int)height, outPoints, maxObjectsInt);
// 构建返回结果
NSMutableArray *detections = [NSMutableArray array];
for (int i = 0; i < detectedCount; i++) {
NSDictionary *point = @{
@"x": @(outPoints[i * 4]),
@"y": @(outPoints[i * 4 + 1]),
@"x2": @(outPoints[i * 4 + 2]),
@"y2": @(outPoints[i * 4 + 3])
};
[detections addObject:point];
}
// 清理资源
CGContextRelease(context);
CGColorSpaceRelease(colorSpace);
callback(@{
@"code": @200,
@"count": @(detectedCount),
@"detections": detections
}, NO);
}
#pragma mark - 图像校正
UNI_EXPORT_METHOD(@selector(rectifyImage:callback:))
- (void)rectifyImage:(NSDictionary *)options callback:(UniModuleKeepAliveCallback)callback {
NSString *base64Image = options[@"image"];
NSArray *points = options[@"points"]; // 期望传入4个点
if (!base64Image || !points || points.count != 4) {
callback(@{@"code": @400, @"message": @"参数错误,需要图片和4个校正点"}, NO);
return;
}
// 转换图片数据
NSData *imageData = [[NSData alloc] initWithBase64EncodedString:base64Image options:0];
UIImage *image = [UIImage imageWithData:imageData];
if (!image) {
callback(@{@"code": @400, @"message": @"图片格式错误"}, NO);
return;
}
// 获取图像数据
CGImageRef cgImage = image.CGImage;
size_t width = CGImageGetWidth(cgImage);
size_t height = CGImageGetHeight(cgImage);
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGContextRef context = CGBitmapContextCreate(NULL,
width,
height,
8,
width * 4,
colorSpace,
kCGImageAlphaPremultipliedLast);
CGContextDrawImage(context, CGRectMake(0, 0, width, height), cgImage);
unsigned char *rgbaData = (unsigned char *)CGBitmapContextGetData(context);
// 准备点数据
int cPoints[8]; // 4个点,每个点x,y
for (int i = 0; i < 4; i++) {
NSDictionary *point = points[i];
cPoints[i * 2] = [point[@"x"] intValue];
cPoints[i * 2 + 1] = [point[@"y"] intValue];
}
// 准备输出缓冲区
int maxBufferSize = width * height * 4;
unsigned char *outBuffer = malloc(maxBufferSize);
int outWidth = 0, outHeight = 0;
// 调用校正接口
int result = yolo_rectify_by_points(rgbaData,
(int)width,
(int)height,
cPoints,
outBuffer,
maxBufferSize,
&outWidth,
&outHeight);
if (result > 0) {
// 创建校正后的图片
CGContextRef outContext = CGBitmapContextCreate(outBuffer,
outWidth,
outHeight,
8,
outWidth * 4,
colorSpace,
kCGImageAlphaPremultipliedLast);
CGImageRef outCGImage = CGBitmapContextCreateImage(outContext);
UIImage *outImage = [UIImage imageWithCGImage:outCGImage];
// 转回base64
NSData *outImageData = UIImagePNGRepresentation(outImage);
NSString *outBase64 = [outImageData base64EncodedStringWithOptions:0];
callback(@{
@"code": @200,
@"image": outBase64,
@"width": @(outWidth),
@"height": @(outHeight)
}, NO);
CGImageRelease(outCGImage);
CGContextRelease(outContext);
} else {
callback(@{@"code": @500, @"message": @"图像校正失败"}, NO);
}
// 清理资源
free(outBuffer);
CGContextRelease(context);
CGColorSpaceRelease(colorSpace);
}
@end
9***@qq.com
- 发布:2026-03-09 09:04
- 更新:2026-03-09 09:04
- 阅读:21
1 个回复
Ask小助手 - Ask社区AI助手
在 iOS 平台,只有原生语言插件(DCUniModule)里用
UNI_EXPORT_METHOD暴露的方法,才能在 uni-app 页面(或 index.uts)里通过uni.requireNativePlugin拿到插件实例后调用。如果 index.uts 里“调用不到”,99 % 是因为插件没有被正确注册或前端调用方式不对。请按下面 3 步排查:
插件必须放在
uni_modules/插件名/utssdk/app-ios/目录下‑ 文件名随意,但必须继承
DCUniModule并用UNI_EXPORT_METHOD暴露方法。‑ 参考官方示例:扩展 module
前端调用时,必须先取到插件实例,再调用方法
注意:
ADYIMGPlugin)必须与原生类名一致。如果仍然提示找不到方法,请确认:
index.uts里直接import原生.m/.swift文件——这是不被支持的,只能通过requireNativePlugin调用。按以上步骤检查后,暴露的方法即可正常在 index.uts 或页面中调用。
要回复问题请先登录或注册
公告
更多>相关问题