【问题标题】:Conversion of image to unsigned char*将图像转换为无符号字符*
【发布时间】:2018-01-04 07:38:51
【问题描述】:

我正在开发一个应用程序,该应用程序使用 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. 从bitmap/base64获取字节数组
  3. 将字节数组传递给 C++
  4. 在 C++ 中将字节数组转换为 unsigned char*(由于 unsigned char* 在 Android/Java 中不可用,我必须将其转换为 C++ 部分)

这里是转换为 unsigned char* 的代码

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

这是 android 中 unsigned char* 转储的开始

"\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\^\

【问题讨论】:

  • 第一个“转储”显然不是实际的图像内容,而是一个 PNG 文件 [或者您在转储该内容时非常“幸运”,但我强烈怀疑您正在转储 PNG 文件,而不是一堆像素值] - 这类似于说“我的 PDF 文件看起来不像我创建它的文本字符串”。
  • 其实我就是这么想的。就像在 iOS 转换代码中一样,您可以看到图像是从原始图像数据在内存中绘制/创建的,然后该图像被转换了,那么 Android 中也有类似的东西吗?我们只有图像数据。我认为位图数据类似于它不应该只有图像数据流的文件信息。实际情况并非如此。

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


【解决方案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);
}
}

希望对你有用,如果有问题请告诉我。

【讨论】:

  • 我在这一行 (*env)->GetByteArrayRegion (env,cBytes, 0, len, (jbyte * )buf);
猜你喜欢
  • 2019-11-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-09-16
  • 2013-11-16
  • 1970-01-01
  • 1970-01-01
  • 2012-06-03
相关资源
最近更新 更多