Android Nexus 10 пустой PNG от JNI ByteArray

Я занимаюсь разработкой приложения с использованием JNI и стороннего движка (Unreal Engine 4), отвечающего за управление графическим конвейером / рендерингом.

Сторонний движок написан на C ++, поэтому необходимо использовать JNI для его соединения с Android.

Приложение требует сохранить на устройстве скриншот того, что отображается на экране (другими словами дамп кадрового буфера).
Сторонний движок предоставляет API, который вызывает пользовательский обработчик, передавая данные о ширине, высоте и цвете экрана.
colordata это пользовательский контейнер uint8 представляет компоненты RGBA.

Мне удалось преобразовать colorData к jbyteArray и передать его в качестве аргумента функции на стороне JAVA.
Со стороны Java все проще: я создаю растровое изображение из byteArray, переворачиваю его и сохраняю как jpg / png через пользовательский AsyncTask,

Эта проблема:
Код прекрасно работает на Samsung Galaxy S4 / Note3 (оба Android 5.0), тогда как на Nexus 10 Android версии 5.1.1 png, который сохраняется, пуст.
Я боюсь, что проблема с этим лежит на более глубоком уровне, чем те, к которым у меня есть доступ, т.е. версия видеокарты / драйверов / ОС, но я не эксперт в этой области, поэтому я хотел бы знать, если кто-то уже испытал подобную проблему или мог бы пролить свет на то, что ее вызывает.

Это код, используемый для соединения движка с Java (я запустил c ++ с этим проектом, поэтому, возможно, в этом фрагменте есть проблемы с владением / памятью. Вы можете исправить меня в этом случае :))

void AndroidInterface::SaveBitmap(const TArray<FColor>& colorData, int32 width, int32 height) {

JNIEnv* env = FAndroidApplication::GetJavaEnv(true);

TArray<FColor> bitmap = colorData;

TArray<uint8> compressedBitmap;

FImageUtils::CompressImageArray(width, height, bitmap, compressedBitmap);size_t len = width*height*compressedBitmap.GetTypeSize();

LOGD("===========Width: %i, height: %i - Len of bitmap element: %i==========", width, height, len);

jbyteArray bitmapData = env->NewByteArray(len);

LOGD("===========Called new byte array==========");

env->SetByteArrayRegion(bitmapData, 0, len, (const jbyte*)compressedBitmap.GetData() );

LOGD("===========Populated byte array==========");

check (bitmapData != NULL && "Couldn't create byte array");

jclass gameActivityClass = FAndroidApplication::FindJavaClass("com/epicgames/ue4/GameActivity");
check (gameActivityClass != nullptr && "GameActivityClassNotFound");

//get the method signature to take a game screenshot
jmethodID saveScreenshot = env->GetMethodID(gameActivityClass, "saveScreenshot", "([BII)V");

env->CallVoidMethod(AndroidInterface::sGameActivity, saveScreenshot, bitmapData, width, height);

env->DeleteLocalRef(bitmapData);

}

Это код Java, отвечающий за конвертацию из byte[] в Bitmap:

public void saveScreenshot(final byte[] colors, int width, int height) {

android.util.Log.d("GameActivity", "======saveScreenshot called. Width: " + width + " height: " + height + "=======");
android.util.Log.d("GameActivity", "Color content---->\n " + Arrays.toString(colors));
final BitmapFactory.Options opts = new BitmapFactory.Options();
opts.inPreferredConfig = Bitmap.Config.ARGB_8888;
final Bitmap bitmap = BitmapFactory.decodeByteArray(colors, 0, colors.length, opts);

final FlipBitmap flipBitmapTask = new FlipBitmap();
flipBitmapTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, bitmap);

}

FlipBitmap — это AsyncTask, отвечающая за сохранение растрового изображения в файл:

private class FlipBitmap extends AsyncTask<Bitmap, Void, File> {

@Override
protected File doInBackground(Bitmap... params) {
final Bitmap src = params[0];
final File file = new File(MainActivity.SCREENSHOT_FOLDER + "screenshot" + System.currentTimeMillis() + ".png");
final Matrix matrix = new Matrix();
matrix.setScale(1, -1);
final Bitmap dst = Bitmap.createBitmap(src, 0, 0, src.getWidth(), src.getHeight(), matrix, false);
try {
final FileOutputStream out = new FileOutputStream(file);
dst.compress(Bitmap.CompressFormat.PNG, 90, out);
out.flush();
out.close();
} catch (Exception e) {
e.printStackTrace();
}

return file;
}

@Override
protected void onPostExecute(File file) {
android.util.Log.d("GameActivity", "FlipBitmap onPostExecute");

if (file.exists()) {
final Intent i = new Intent(Intent.ACTION_SENDTO);
i.setData(Uri.parse("mailto:" + Globals.Network.MAIL_TO));
i.putExtra(Intent.EXTRA_SUBJECT, Globals.Network.MAIL_SUBJECT);
i.putExtra(Intent.EXTRA_TEXT, mBodyEmail);
i.putExtra(Intent.EXTRA_STREAM, Uri.parse("file://" + file.getAbsolutePath()));
startActivity(Intent.createChooser(i, "Invia via email"));
}

}
}

Заранее спасибо!

1

Решение

Задача ещё не решена.

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]