Hi,
I am trying to save a png file from a screenshot taken from c++ code on an Android device.
To save the screenshot I first attach my class to the OnScreenshotCaptured
delegate, then I convert the compressed TArray
to a TArray
using FImageUtils::CompressImageArray
to a jbyteArray
and pass the byte[
] to the Java part of the application where the Bitmap is created and saved as a png.
The png file is properly saved on a Samsung Galaxy S4, but on a Nexus 10 the same code produces a white png (or a black jpg if I change format).
What could be the cause of that?
I noticed that on the Galaxy S4 the compressedBitmap TArray has a resolution of 1024x576 instead of the native 1920x1080 whereas on the Nexus 10 the log shows a resolution of 921x576 (instead of the native res of 2560 x 1600).
If I take the screenshot including SlateUI elements, on the Samsung Galaxy S4 everything is saved correctly, whereas on Nexus10 I can only see Slate elements on a black backround.
The delegate callback is as follows:
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);
}
Whereas the java code that handles the png creation is:
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 is an AsyncTask that just creates the png file on another thread.