gpt4 book ai didi

java - JNI : RGB565 Bitmap to Grayscale - how to pass in JNI changed data back to Java?

转载 作者:太空宇宙 更新时间:2023-11-04 13:39:37 26 4
gpt4 key购买 nike

在 JNI 中,我有一个指向 8 位整数数组 (uint8_t*) 的指针。我想将它的数据传递给 Java 部分。

我的问题是,数组中的数据必须是 uint_8 格式,因为我是从格式为 RGB565 的位图中获取它的颜色信息,我想将其更改为灰度:

Java 部分:

    private void loadJPEG(String fileName) {

Bitmap old = BitmapFactory.decodeFile(fileName);
Bitmap bmp = old.copy(Config.RGB_565, false);
byte[] grayScaledBitmap = new byte[]{};

if (bmp != null && bmp.getConfig() == Bitmap.Config.RGB_565) {

ShortBuffer rgbBuf = ShortBuffer.allocate(bmp.getWidth() * bmp.getHeight());

bmp.copyPixelsToBuffer(rgbBuf);

grayScaledBitmap = convertToLum(rgbBuf.array(), bmp.getWidth(), bmp.getHeight());
}
}

private native byte[] convertToLum(short[] data, int w, int h);

C++部分:

void convertRGB565ToGrayScale(JNIEnv* env, uint8_t* src, unsigned int srcWidth, unsigned int srcHeight, uint8_t* dst) {
unsigned int size = srcWidth * srcHeight;
uint16_t rgb;
uint16_t r;
uint16_t g;
uint16_t b;

for (unsigned int i = 0; i < size; i++) {
rgb = ((uint16_t*) src)[i];
uint16_t tmp = (uint16_t) (rgb & 0xF800);
tmp = tmp >> 8;

r = (uint16_t) ((rgb & 0xF800) >> 8); //to rgb888
g = (uint16_t) ((rgb & 0x07E0) >> 3);
b = (uint16_t) ((rgb & 0x001F) << 3);

dst[i] = (uint8_t) (((r << 1) + (g << 2) + g + b) >> 3); //to grayscale
}
}


JNIEXPORT jbyteArray JNICALL Java_com_qualcomm_loadjpeg_LoadJpeg_convertToLum(JNIEnv* env, jobject obj, jshortArray img, jint w, jint h) {

jshort* jimgData = NULL;
jboolean isCopy = 0;
jbyte* grayScaled;
jbyteArray arrayToJava

DPRINTF("%s %d\n", __FILE__, __LINE__);

if (img != NULL) {
// Get data from JNI
jimgData = env->GetShortArrayElements(img, &isCopy);

uint8_t* lum = (uint8_t*) fcvMemAlloc(w * h, 16);
convertRGB565ToGrayScale(env, (uint8_t*) jimgData, w, h, lum);
grayScaled = (jbyte*) lum;
arrayToJava = env->NewByteArray(w*h);
env->SetByteArrayRegion(arrayToJava, 0, w*h, grayScaled);

env->ReleaseShortArrayElements(img, jimgData, JNI_ABORT);
fcvMemFree(lum);


DPRINTF("%s %d Done\n", __FILE__, __LINE__);
}
return arrayToJava;
}

错误来自 SetShortArrayRegion 函数:

No source available for memcpy() at [hexadecimal adress]
No source available for ioctl() at ...

编辑>> 上面的错误不再出现,它是由于通过 fcvmemfree 释放内存不当造成的,代码被重新编辑。我在用来自 convertRGB565ToGrayScale 的数据填充 jbyteArray arrayToJava 时仍然有问题,在 SetByteArrayRegion 调用后它总是空的。问题还是:

我应该如何将更改后的数据传递给 Java 部分?

最佳答案

jshort 相当于一个 16 位整数。 uint8_t 是 8 位无符号字符类型:

http://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/types.html

http://en.cppreference.com/w/c/types/integer

因此,您不能仅仅将一种指针类型转换为另一种指针类型,尤其是不同大小的类型。存在可以发挥作用的严格别名规则的问题:

What is the strict aliasing rule?

所以您应该尝试使用 int16_t 作为类型。根据上述链接中的 JNI 文档,这与 jshort 的定义相匹配。

关于java - JNI : RGB565 Bitmap to Grayscale - how to pass in JNI changed data back to Java?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28251799/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com