Looking to let a user export a screenshot or other image from within a webgl app so I want to give a user the contents of a Texture2D in effect.
As much a js/php question as Unity really
Now I can save image to a server and then direct them to the URL but seems very wasteful when the data is to hand so can it be done another way?
Yes but does not handle download through webgl right? It is not hard to do the grab part with a Render Texture, its offering to download.
Guess it may have to be uploaded to a URL and the user pointed to that
Thanks for the solution. Does anyone have an idea to convert/expand this to a generic file downloader to cover other content types like doc, pdf…etc.? I’m not a Javascript coder but when I skimmed the code I couldn’t find anything image specific except the content type. Any ideas?
This is the one I use personally for different file types. You simply pass it a byte[ ] array, the length of the byte array and the desired file name.
The mouse event is a little bit of a hack to get it to download but otherwise it’s fairly simple code.
DownloadFile : function(array, size, fileNamePtr)
{
var fileName = UTF8ToString(fileNamePtr);
var bytes = new Uint8Array(size);
for (var i = 0; i < size; i++)
{
bytes[i] = HEAPU8[array + i];
}
var blob = new Blob([bytes]);
var link = document.createElement('a');
link.href = window.URL.createObjectURL(blob);
link.download = fileName;
var event = document.createEvent("MouseEvents");
event.initMouseEvent("click");
link.dispatchEvent(event);
window.URL.revokeObjectURL(link.href);
}
C# example in case of a screenshot (CaptureScreenshotAsTexture introduced in 2018.1 function I believe):
I just tested JJJohan’s solution, and I give it high marks. I was replacing a hacky no-longer-working solution from 2015, and this simplified my code substantially.
I tried both solutions, even in an empty project using 2018.3.5f1 and my images comes up pitch black (I believe transparent if it’s png). sumpfkraut , JJJohan do you have any ideas what might be wrong?
I tried a lot of stuff past few hours but couldn’t get it to work so had to ask at this point
I just tried again using exact same js you posted and;
public void DownloadScreenshot()
{
var texture = ScreenCapture.CaptureScreenshotAsTexture();
byte[] textureBytes = texture.EncodeToJPG();
ImageDownloader(System.Convert.ToBase64String(textureBytes), imageFilename);
}
byte array looks good in editor, I mean I see some values which shouldn’t be the case with pitch black image. I’m using .net 4.x runtime and api compatibility level. managed stripping level is low. tried using both asm and web assembly.
edit: this is an empty project so there is no other scripts, post processing or fancy camera stuff.
I see that you are encoding the data as base64 before sending it to the jslib. If you’re using the jslib snippet I posted then that won’t work, as it expects you to just pass the byte array as such:
I’ve slightly modified my jslib snippet a few posts above so it cleans up better and uses Utf8ToString since it looks like Pointer_Stringify is deprecated in newer Emscripten versions.
I tried your version before and again today but I’m getting same results. At this point I’m pretty sure it’s not code related but there’s something else (locale? unity/build settings? version?). Thanks a lot to you both for responding guys, I really appreciate it. I’ll post again if I can find the issue
Edit: actually I just tried it on a totally different machine with EN-US locale (I’m saying this as I had problems with that before) and had the same result. I’m totally confused now.
Edit: It all works now, I think it was because of my wrong wait till end of frame part I never checked. Can’t believe how many hours I wasted on that Thanks again for all the help!