将图像转换为无符号字符*

时间:2018-01-04 07:38:52

标签: android c++ objective-c android-ndk java-native-interface

我正在开发一个使用NDK与外部SDK通信的应用程序,用于处理图像数据。用于图像的SDK的输入类型是unsigned char *。在iOS中它工​​作正常,下面是在那里使用的Objective-C代码。

unsigned char *dataImage     =   (unsigned char*) 
malloc(bytesPerRow*height);
CGColorSpaceRef colors  =   CGColorSpaceCreateDeviceRGB();
CGContextRef context    =   CGBitmapContextCreate(dataImage, width,height, BITSPERCOMPS, bytesPerRow, colors, 
(CGBitmapInfo)kCGImageAlphaNoneSkipLast);
CGContextDrawImage(context, CGRectMake(0.f, 0.f, width, height), imageRef);

此dataImage传递给SDK并返回正确的结果。现在,我正在尝试在Android中生成类似的图像数据流,但SDK始终返回false。以下是我在Android中将图像转换为unsigned char *所执行的步骤,

  1. 获取位图/ base64(同时尝试使用)图像数据
  2. 从位图/ base64获取字节数组
  3. 将字节数组传递给C ++
  4. 在C ++中将字节数组转换为unsigned char *(因为unsigned char *在Android / Java中不可用,我必须在C ++部分转换它)
  5. 以下是转换为unsigned char *

    的代码
    int len = (*env)->GetArrayLength (env,image);
    unsigned char* buf = malloc(len);
    (*env)->GetByteArrayRegion (env,image, 0, len, (jbyte *) buf);
    

    这是android

    中unsigned char * dump的开头
    "\x89PNG\r\n\x1a\n"
    

    这是在Objective C中生成的unsigned char *

    A\^X
    \M^?B\^Y\M^?B\^Y\M^?B\^Z\M^?B\^\
    \M^?B\^\
    \M^?C\^]\^N\M^?D\^]\^N\M^?E\^_\^P\M^?D\^^\^O\M^?A\^\
    

1 个答案:

答案 0 :(得分:1)

我假设您对Android NDK非常熟悉,如果没有,请查看here。我没有测试它,但我会像这样接近它:

1)加载位图并从outputStream中获取byteArray:

Bitmap bmp; // your bitmap 
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();  
bmp.compress(Bitmap.CompressFormat.PNG, 100, byteArrayOutputStream);
byte[] byteArray = byteArrayOutputStream .toByteArray();
// Call native function defined below
passByteArrayToJni(byteArray);

2)在你班级的某个地方声明本地功能

// Declare native function in NDK
public native passByteArrayToJni(byte[] byteArray);

3)在.cpp文件中:

extern "C" {
JNIEXPORT void JNICALL Java_com_packageX_ClassY_passByteArrayToJni( JNIEnv* env, jobject thiz, jbyteArray byteArray);
{
    // Reads byte array to * cBytes
    jbyte * cBytes = env->GetByteArrayElements(byteArray, &isCopy);
    // Gets the size
    jsize len = (*env)->GetArrayLength(env, byteArray);

    // Get region
    unsigned char* buf = malloc(len);
    (*env)->GetByteArrayRegion (env,cBytes, 0, len, reinterpret_cast<jbyte*>(buf));


    // Releases array when done with it.
    env->ReleaseByteArrayElements(byteArray, cBytes, JNI_ABORT);
}
}

希望这对你有用,请告诉我是否有任何问题。