Take screenshot in server

Hi all,

I want to write some C# code which runs in a server. No UI or web page involved.

public static void ExportScreenshots(string babylonFilePath, string screenshotsOutputFolderPath)
{
//Load .babylon file.
// render the scene
//take screenshot from each camera and save the image in the output folder.
}

One thing I could think of is, Implement C# code to:

  1. Read Vertices, Indices, Normals, UVs etc. from the file.
  2. Render them using DirectX/SharpDX to a a WARP device.

this.device3d = new SharpDX.Direct3D11.Device(SharpDX.Direct3D.DriverType.Warp,
SharpDX.Direct3D11.DeviceCreationFlags.None
| SharpDX.Direct3D11.DeviceCreationFlags.None);
3. Export images from the underlying 2dTexture of this 3d device.

The problem with this is, I will end up implementing all the logic of babylon.js.

Can you please suggest a better approach?

@Deltakosh, I came across your JsBridge/ChakraBridge. It is a nice implementation.
Can I use this bridge to use babylon.js and other babylon’s .js files to load the scene and take screenshots?

Thanks in advance.

1 Like

@trevordev may have a better solution :slight_smile:

1 Like

How? Please give a clue

I would imagine you could get that all working with Chrome headless (selenium). I wonder how Remix3D does it, because they have a series of screenshots and you can see in the model metadata the camera/environment positions.

1 Like

I managed to get the puppeteer api (GitHub - GoogleChrome/puppeteer: Headless Chrome Node API) to work in a similar use case but using nodejs instead of c#. Like Brian mentioned this is just a headless browser so babylonjs can run without any modification.

If you need gpu acceleration, cheapest vm I was able to find was 1.80 USD/hr which was a windows vm with GRID drivers which allows puppeteer to initialize the gpu.

If cpu is all that is needed you could look at this repo (GitHub - TrevorDev/babylonServer) and ignore anything about nvidia drivers or running in non-headless mode.

2 Likes

Thank you. I will try selenium. I have actually written code to render Babylon file in memory using SharpDX. But could not understand how to set textures other than DiffuseTexture. My models are static. No game logic involved. What all i need is a Babylon viewer. Not a game engine. So, I hope if I could render my model using SharpDX, I can use my Babylon models in Windows apps also.

Hi all, I am now trying with Selenium.
I have a javascript function like this.

    function TakeScreenshotInMemory (camera, callback) {
                var scene = camera.getScene();
                var engine = scene.getEngine();
                BABYLON.Tools.CreateScreenshotUsingRenderTarget(engine, camera, { precision: 1 }, callback);
            }

But I want the function to return the actual base64 encoded image string. I do not want any callbacks.
I want to invoke this from Selenium.
How can I achieve it?

Is there a mechanism in javascript to wait for the callback to be called and then return the result?

I am stuck here. Please help.

This is untested, but couldn’t you just use a promise?

var screenshotPromise = new Promise(function(resolve, reject) {
  TakeScreenshotInMemory(camera, (data) => {
    resolve(data);
  }
});

// this will block until the callback is called
screenshotPromise.then(function(data) {
  console.log(data);
});
1 Like

Thank you @brianzinn, Your solution works perfectly.
However, selenium has a functionality for this.

 IJavaScriptExecutor js = driver as IJavaScriptExecutor;
 var script = "var callback = arguments[0]; " +
                "TakeScreenshotInMemoryFromActiveCamera(callback);";
 var base64Image = js.ExecuteAsyncScript(script);