Defold Screenshot - Capture the moment!

Umm, you’re right, how silly of me.

Please take a moment to picture me with a jesters hat bouncing around the office looking like a fool…

5 Likes

@xndr: The extension should work for windows now.

6 Likes

Yes! It’s work. Very-very much thanks!

3 Likes

Got the next error on MacOS (editor 2, screenshot v1.5). Build && run from editor:

Undefined symbols for architecture x86_64
"__ZSt20__throw_length_errorPKc", referenced from:
      __ZNSt6vectorIhSaIhEE14_M_fill_insertEN9__gnu_cxx17__normal_iteratorIPhS1_EEmRKh in lib126eb502-6aef-474a-b00b-61d59df86846.a(lodepng.c_0.o)
      __ZNSt6vectorIhSaIhEE15_M_range_insertIPhEEvN9__gnu_cxx17__normal_iteratorIS3_S1_EET_S7_St20forward_iterator_tag in lib126eb502-6aef-474a-b00b-61d59df86846.a(lodepng.c_0.o)

On android build extension runs well.

edit: conflicted with https://github.com/GameAnalytics/GA-SDK-DEFOLD (game analytics extension)
try to understand, how to fix it
temporary fixed by copy ext.manifest settings from GA to screenshot

1 Like

It’s been a while. Think you could do the same for HTML5? :wink:
I think you can, and I really hope so! (when you have time to look again, ofc)

I spent a few days on Stack Overflow already. Maybe I can at least save you some time there. Pretty sure I’ve figured out why screenshots are all black, and a solution to make it work. I am struggling to implement it though, and hoping you or some other experienced folks here might be able to spot an obvious way to do this.

The official source (bottom half of section 2.2 WebGL specs) says:
“By default, after compositing the contents of the drawing buffer shall be cleared to their default values”

Then it goes on to say: “attempting to perform operations using this context as a source image after the rendering function has returned can lead to undefined behavior. This includes readPixels or toDataURL calls, using this context as the source image of another context’s texImage2D or drawImage call, or creating an ImageBitmap [HTML] from this context’s canvas.”

The Solution may be: “Techniques like synchronous drawing buffer access (e.g., calling readPixels or toDataURL in the same function that renders to the drawing buffer) can be used to get the contents of the drawing buffer.”

I was trying to do that on my own, so not to bother you with it, but I feel like I am in way over my head at this point. All I’ve manage to do, is possibly confirm that we are in fact getting the cleared buffer, and not the drawing buffer.
Adding glClear(GL_COLOR_BUFFER_BIT) to this code in the Screenshot extension:

static GLubyte* ReadPixels(unsigned int x, unsigned int y, unsigned int w, unsigned int h) {
...
#if ...
...
#elif defined (__EMSCRIPTEN__)
	glClear(GL_COLOR_BUFFER_BIT);
#endif
	glReadPixels(x, y, w, h, GL_RGBA, GL_UNSIGNED_BYTE, data);
	return data;
}

Gives screenshot like this (orange instead of black):

I tried doing a bunch of other stuff, but that’s all I got.

Sorry I couldn’t help more! :persevere: (if this even helps at all)

1 Like

Hi guys, I’m looking to send a screenshot to Facebook Instant API. If this plugin can’t do it, is there an alternative way to capture a bitmap in Defold and send it on to the Facebook Instant API to be shared in a post?

I struggled with this problem while developing the Instant Games extension but didn’t find a working solution at the time. The issue is reported here: https://github.com/defold/extension-fbinstant/issues/9

2 Likes

I can confirm the latest version of Defold Screenshot works great in HTML5 and Facebook Instant!

7 Likes

Quick question: Can Defold Screenshot save 8 bit pngs (to save space)?

No, but it could probably be added.

1 Like

Thank you for making this extension. Basically it works, but I’m still struggling with some things, that don’t really have to do with the screensaver itself.

I’m implementing the screensaver in an application where I want the user to actually find the picture on their system. I’m working on a Mac. The standard location is the user/library/application Support folder. That’s a hidden folder so surely the safest place where nobody outside of tech will ever find a saved file.

How could I save the screenshot in a place that is more accessible to users? I understand that this could be different for each device.

1 Like

If you wish your user to choose the folder himself then use DefDiags:

Or:

1 Like

Got it.
Thanks!

1 Like

I’d like to take a screenshot and share it as a .png in HTML.

I’m using the code from the screenshot extension, but when the screenshot has been captured, this happens in vanilla Chrome v88:

The code:

local function download_base64_image(base64_image)
	local img_for_download = string.gsub(base64_image, "image/png", "image/octet-stream")
	html5.run("window.location.href='"..img_for_download.."';")
end

local function html5_screenshot_callback(self, base64_img)
	download_base64_image(base64_img)
end

function init(self)
	screenshot.png(html5_screenshot_callback)
end

Has anyone seen this behaviour before? There seem to be some security stuff going on.

Do you have any extensions enabled which may be interfering? / Are you testing on a remote server?

Nope.

Yes, although the same result happens when using “Build HTML5”.

I don’t know if you can trigger a cross-origin location change without user interaction. I’d take a different approach:

defos.on_interaction(function ()
  html5.run([[
    const element = document.createElement('a')
    element.setAttribute('href', ']] .. base64_image .. [[')
    element.setAttribute('download', 'screenshot.png')

    element.style.display = 'none'
    document.body && document.body.appendChild(element)

    element.click()

    document.body && document.body.removeChild(element)
  ]])
end)

(but I may be wrong)

Another thing to be careful about is to make sure the canvas isn’t tainted by rendering cross-origin textures into it, but I’m not sure how that could happen in Defold.

6 Likes

This worked straight up. Incredible. Thanks so much!

4 Likes

I’m using the latest Screenshot library 1.8.0.
Defold 1.2.180.
Getting black screenshot on Android 9

screenshot.png(function(self, image, w, h)
					local path = sys.get_save_file(sys.get_config("project.title"), "screenshot1_cb.png")
					local f = io.open(path, "wb")
					f:write(image)
					f:flush()
					f:close()
					print(path)
					share.file(path, "Check my score !!")
				end)

Anyone else having the same issue?

This is very likely caused by the upgrade to Open GL 3. I’m happily accepting pull requests!