首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >为什么JNI GetByteArrayElements不保留像素步幅?

为什么JNI GetByteArrayElements不保留像素步幅?
EN

Stack Overflow用户
提问于 2022-04-07 15:18:41
回答 1查看 75关注 0票数 0

我需要将YUV_420_8888图像从Android传递到C++以进行处理。因此,我将图像平面转换为ByteArray,然后将它们发送到C++函数。

代码语言:javascript
复制
val yBuffer: ByteBuffer = image.planes[0].buffer            
val uBuffer: ByteBuffer = image.planes[1].buffer
val vBuffer: ByteBuffer = image.planes[2].buffer
val yByteArray = ByteArray(yBuffer.remaining())
val uByteArray = ByteArray(uBuffer.remaining())
val vByteArray = ByteArray(vBuffer.remaining())
yBuffer.get(yByteArray)
uBuffer.get(uByteArray)
vBuffer.get(vByteArray)
return NativeCppClass::process(yByteArray, uByteArray, vByteArray)

y平面具有像素步长1,uv平面具有像素步长2。当我看到uByteArrayvByteArray时,它们正在查看相同的内存块,v平面在u平面之前启动。更特别的是,它们看起来是这样的,例如:

代码语言:javascript
复制
vByteArray = [0, 1, 2, 3, 4, 5, 6]
uByteArray =    [1, 2, 3, 4, 5, 6, 7]

在此基础上,我希望我们在下面有这样的发言。为了便于参考,我们将其命名为(*)

代码语言:javascript
复制
uByteArray.begin - vByteArray.begin = 1; // begin is just a way to express the starting point of a byte array

我还有一个ByteArray_JNI,可以将ByteArray从Kotlin转换为一个名为CppByteArray的类。它们看起来是这样的:

代码语言:javascript
复制
class ByteArray_JNI {
public:
    using CppType = CppByteArray;
    using JniType = jbyteArray;
    using Boxed = ByteArray_JNI;

   static CppType toCpp(JNIEnv *jniEnv, JniType byteArray) { 
      
      return CppType{byteArray, jniEnv};
    }
}

class CppByteArray {
public: 
    CppByteArray(jbyteArray data, JNIEnv *env) : array_(env, data) {
        jboolean copied = false;
        buffer_ = (uint8_t *)env->GetByteArrayElements(data, &copied);
        // copied out param is false at this stage, so no copy
        size_ = env->GetArrayLength(data);
    }
    const uint8_t* data() const {
      return buffer_; 
    }
private: 
    djinni::GlobalRef<jbyteArray> array_;
    uint8_t *buffer_ = nullptr;
    jsize size_ = 0;
}

但是,上面的语句(*)在C++中不是真的:

代码语言:javascript
复制
class NativeCppClass {
public:
    static CppByteArray process(CppByteArray &&y_array, CppByteArray &&u_array, CppByteArray &&v_array) {
          auto u_begin = u_array.data(); 
          auto v_begin = v_array.data();
          // u_begin - v_begin = 462848 (not 1 as expected). My image has dimensions 1280x720, just in case it is related to the number 462848. 
         return something; 
    }
}

为什么是u_begin - v_begin = 462848,而不是1?在这种情况下,GetByteArrayElements不执行副本。在调用copied之后,输出参数GetByteArrayElements为false。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-04-08 08:20:32

根据ByteBuffer文档:https://developer.android.com/reference/kotlin/java/nio/ByteBuffer#get_2get将字节复制到目标数组中。在本例中,yByteArrayuByteArrayvByteArray是从缓冲区复制的。这解释了为什么指针中的偏移量不是1。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/71784778

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档