0 votes

From demo examples, I know I can do screen capture as follows:

    get_viewport().queue_screen_capture()
    # Let two frames pass to make sure the screen was captured
    yield(get_tree(), "idle_frame")
    yield(get_tree(), "idle_frame")
    # Retrieve the captured image
    var img = get_viewport().get_screen_capture()

But how to pass this image to custom module? For iOS module, Can I do something like:

    postToModule({"image": img})

? How to retrieve it as an UIImage? And what about android module? How to pass and convert it to a Bitmap?

in Engine by (32 points)

get_screen_capture() gives you an Image, which is nothing more than a 2D array of colors.
What are you calling a "module" here? Are you talking about a C++ Godot module?

Yes, C++ (Objective C++) module for iOS and Java module for Android. I need both platforms to work :D
I know I can retrieve it at Objective C++ or Java module by "Dictionary", but don't know how to convert it to UIImage (for iOS) and Bitmap (for Android). I am doing so for that I want to share the screenshots to social network like Facebook or Twitter.

First, make your class (or whatever you are doing) have a function that accepts an Image, then... as I said, Image is really just a grid of colors. It depends on what the iOS/Android API wants you to provide, is that a PNG, JPG? I never did that before and have no idea if it's the best idea to share screenshots, but Godot mostly provides just that, as far as I know. Image eventually has a save_png function, maybe you can refer to the produced file in your module code, as if it was a picture on the phone?

Thank you for your help. I seem to see some light. Where does the save_png save file? If it is at "res://", then how can I get it from C++ and Java module? i.e. How to read file of "res://" from C++ and Java module?

The image will end up where you want it to be, there is a path argument. On mobile if you use a path like "user://screen.png" it will end up in a writable folder.
Also, I read the API wants you a Bitmap or UIImage. There is maybe a way to pass them the colors array directly instead of writing the file to disk.

Yes, Bitmap or UIImage, that's what I want :) , but I don't know how to convert these colors into them. :(
As for save file to disk, what kind of path I can give? If I set path argument as "user://screen.png", is it still the same path name: "user://screen.png" on mobile?

Me neither.
Does the API let you create a UIImage/Bitmap and set the colors from a char* array? You should check the docs about that.
user:// is a unified path specific to Godot. It actually targets different paths depending on the OS. On Windows it's AppData, on Android and iOS it must be somewhere else (but I can't find it in the doc right now). The reason why is that on mobile the filesystem is more restricted.

2 Answers

0 votes

Thank you Zylann, I managed to find a way because of your hint. You really saved my life. ^_^ It's something like the following:
GDscript:

func screen_capture():
   ......
   #Retrieve the captured image and store in the member var img
   img = get_viewport().get_screen_capture()
   #call Java singleton to get path
   JavaSingleton.askForPath()

func _on_call_back(path):
   if path != "":
    #save image to Android device path
    img.save_png(path)
    #call Java singleton to share the image
    JavaSingleton.postToShare()

Java singleton:

public void askForPath() {
     String fileName = "Screen.png";
     String dirPath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/Screenshots";
     File dir = new File(dirPath);
     if(!dir.exists())
          dir.mkdirs();
     file = new File(dirPath, fileName);    
     GodotLib.calldeferred(instance_id, "_on_call_back", new Object[]{file.toString()});
}
public void postToShare(){
     ......
}

I know it's not elegant at all, but it gets my job done. It's not the best answer. I hope someday someone can give a smarter solution to pass the colors array directly instead of writing the file to disk as you said. Hope my answer can help someone who needs it. Thanks again! Zylann!

by (32 points)
0 votes

A good alternative for that. is using data dir returned by the OS class

const SAVE_IMAGE_FILENAME = 'godot-win-image-cache.png'
const SAVED_IMAGE_PATH = 'user://' + SAVE_IMAGE_FILENAME

var SCREENSHOT_ABSOLUTE_PATH = OS.get_data_dir() + SAVE_IMAGE_FILENAME

func pressed():
    get_viewport().queue_screen_capture()
    yield(get_tree(), 'idle_frame')
    yield(get_tree(), 'idle_frame')

    # get screen capture
    get_viewport().get_screen_capture().save_png(SAVED_IMAGE_PATH)

    postToModule({"image": SCREENSHOT_ABSOLUTE_PATH})
by (71 points)
Welcome to Godot Engine Q&A, where you can ask questions and receive answers from other members of the community.

Please make sure to read How to use this Q&A? before posting your first questions.
Social login is currently unavailable. If you've previously logged in with a Facebook or GitHub account, use the I forgot my password link in the login box to set a password for your account. If you still can't access your account, send an email to webmaster@godotengine.org with your username.