You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android中JNI C函数向Java返回未知大小数组及相关问题

关于MATLAB Coder转C+JNI的两个问题解答

问题1:用byteArray传递uint8三维矩阵Vrecorded的逻辑是否正确?

直接用Java的byte[]传递MATLAB的uint8三维矩阵存在两个关键隐患,不能默认逻辑正确:

  • 符号不匹配:Java的byte是有符号类型(范围-128127),而MATLAB的`uint8`是无符号类型(0255)。当uint8值大于127时,转成byte会变成负数(比如uint8(128)对应byte(-128)),若C层直接按有符号解析,会得到错误数值。解决办法是在C层接收时,把byte值转成无符号:(uint8_t)(jbyte_val & 0xFF),确保数值正确映射。
  • 存储顺序不匹配:MATLAB默认采用列优先(column-major)存储三维数组,而Java/C通常用行优先(row-major)。比如Vrecorded(240×320×F)在MATLAB中的存储顺序是:先遍历所有行(240个元素),再遍历列(320列),最后遍历帧(F帧)。如果Java端直接按行优先展平数组传递,C层解析出来的矩阵维度会完全混乱。必须保证Java端展平数组的顺序和MATLAB/C层的存储顺序一致,才能正确还原三维矩阵。

处理好这两个点后,用byteArray传递的逻辑是可行的。

问题2:编译前未知矩阵I的尺寸,如何返回至Java并显示?

由于JNI无法直接返回动态尺寸的多维数组,推荐以下两种实用方案:

方案1:返回自定义Java对象

  1. 在Java端定义承载结果的类:
public class DetectedVideoResult {
    public int width;    // 裁剪后单帧宽度
    public int height;   // 裁剪后单帧高度
    public int frameCount; // 总帧数
    public byte[] pixelData; // 展平后的像素数据(遵循MATLAB列优先顺序)
}
  1. 在JNI函数中,创建该类实例并填充数据:
    • 用FindClass获取类引用,GetFieldID获取字段ID
    • 调用NewObject创建实例,SetIntField设置尺寸值,SetObjectField设置byte[]数据
  2. Java端接收对象后,根据width/height/frameCount将pixelData还原为三维视频矩阵。

方案2:返回包含尺寸和数据的Object数组

JNI函数返回Object[],其中第一个元素是int[]类型的尺寸数组(比如new int[]{width, height, frameCount}),第二个元素是byte[]类型的像素数据。Java端接收后先解析尺寸,再处理数据。

屏幕显示处理

Java端拿到数据后,逐帧将byte[]转换为可显示的图像:

  • 若为RGB格式,创建BufferedImage时指定BufferedImage.TYPE_3BYTE_BGR(注意MATLAB的RGB顺序可能和Java的BGR对应,需根据实际情况调整)
  • 把单帧像素数据写入BufferedImage的DataBuffer,然后用Swing的JLabel/Canvas或者Android的ImageView渲染每一帧,实现视频播放。

内容的提问来源于stack exchange,提问作者Matheus Fortunato Alves

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 08:17:27