Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

How do I let the user load an image from their harddrive into a WebGL app?

Discussion in 'WebGL' started by Mikael-H, Jan 21, 2016.

  1. Gondavid31

    Gondavid31

    Joined:
    Jun 8, 2021
    Posts:
    3
    Hi! I used @sumpfkraut solution on unity 2020.3.

    On desktop firefox and Chrome works perfectly, but I can't manage to open the file browser on mobile chrome nor opera (trying on an android phone), any idea why?

    I undestand the C# blob. No idea of Javascript!
    Thanks!
     
  2. sumpfkraut

    sumpfkraut

    Joined:
    Jan 18, 2013
    Posts:
    241
    Updated scripts...
    Examples:
    Code (CSharp):
    1. using UnityEngine;
    2. using UnityEngine.UI;
    3.  
    4. public class WebGLUpDownExamples : MonoBehaviour
    5. {
    6.     public static WebGLUpload _webGLUpload = null;
    7.     public static WebGLDownload _webGLDownload = null;
    8.     private void Awake()
    9.     {
    10.         _webGLUpload = GetComponent<WebGLUpload>();
    11.         _webGLDownload = GetComponent<WebGLDownload>();
    12.     }
    13.  
    14.     private void UploadZip()
    15.     {
    16.         //Upload a zip file
    17.         _webGLUpload.UploadFile(WebGLUpload.FileExtension.zip);
    18.     }
    19.  
    20.     private void UploadTexture(WebGLUpload.ImageFormat imageFormat)
    21.     {
    22.         //Upload a Texture and don't downsize the image (0)
    23.         _webGLUpload.UploadTexture(imageFormat, 0, true, null, null);
    24.     }
    25.  
    26.     private void UploadTextureToMaterial(WebGLUpload.ImageFormat imageFormat, Material mat)
    27.     {
    28.         //Upload a Texture and set the material texture
    29.         _webGLUpload.UploadTexture(imageFormat, 1024, true, mat, null);
    30.     }
    31.  
    32.     private void UploadTextureToImage(WebGLUpload.ImageFormat imageFormat, Image img)
    33.     {
    34.         //Upload a Texture and set the image sprite
    35.         _webGLUpload.UploadTexture(imageFormat, 1024, true, null, img);
    36.     }
    37.  
    38.     private void DownloadFile(byte[] bytes)
    39.     {
    40.         _webGLDownload.DownloadFile(bytes, "myFilename", "myExtension");
    41.     }
    42.  
    43.     private void DownloadZip()
    44.     {
    45.         ////Zip example(Zip / gzip Multiplatform Native Plugin from the asset store)
    46.         ////----
    47.         //lzip.inMemory mZip = new lzip.inMemory();
    48.         //string myText = "Some text";
    49.         //byte[] bytes = System.Text.Encoding.ASCII.GetBytes(myText);
    50.         //lzip.compress_Buf2Mem(mZip, 9, bytes, "data/" + "myData.dat", null, null);
    51.         //Texture2D tex = null;
    52.         //lzip.compress_Buf2Mem(mZip, 9, tex.EncodeToJPG(), "tex/" + "texName.jpg", null, null);
    53.         //byte[] bZip = mZip.getZipBuffer();
    54.         //_webGLDownload.DownloadFile(bZip, "myZipFilename", "zip");
    55.         //bZip = null;
    56.         //lzip.free_inmemory(mZip);
    57.     }
    58.  
    59.     private void DownloadTexture(Texture2D tex, WebGLDownload.ImageFormat imageFormat)
    60.     {
    61.         byte[] texBytes;
    62.         if (imageFormat == WebGLDownload.ImageFormat.png) texBytes = tex.EncodeToPNG();
    63.         else texBytes = tex.EncodeToJPG();
    64.         _webGLDownload.DownloadFile(texBytes, "texFileName", imageFormat.ToString());
    65.     }
    66.  
    67.     private void DownloadScreenshot()
    68.     {
    69.         _webGLDownload.GetScreenshot(WebGLDownload.ImageFormat.jpg, 1, "");
    70.     }
    71. }

    .jslib's (under a “Plugins” subfolder in your Assets folder -> https://docs.unity3d.com/Manual/webgl-interactingwithbrowserscripting.html)
    DownloadFile.jslib
    Code (JavaScript):
    1. var DownloadFilePlugin = {
    2.     DownloadFileJsLib : function(array, size, fileNamePtr)
    3.     {
    4.         var fileName = UTF8ToString(fileNamePtr);
    5.  
    6.         var bytes = new Uint8Array(size);
    7.         for (var i = 0; i < size; i++)
    8.         {
    9.            bytes[i] = HEAPU8[array + i];
    10.         }
    11.  
    12.         var blob = new Blob([bytes]);
    13.         var link = document.createElement('a');
    14.         link.href = window.URL.createObjectURL(blob);
    15.         link.download = fileName;
    16.  
    17.         var event = document.createEvent("MouseEvents");
    18.         event.initMouseEvent("click");
    19.         link.dispatchEvent(event);
    20.         window.URL.revokeObjectURL(link.href);
    21.     }
    22. };
    23. mergeInto(LibraryManager.library, DownloadFilePlugin);
    UploadFile.jslib
    Code (JavaScript):
    1. var UploadFilePlugin = {
    2.   UploadFileJsLib: function(gameObjectName, methodName, fileExtension) {
    3.     var gameObject = UTF8ToString(gameObjectName);
    4.     var method = UTF8ToString(methodName);
    5.     var format = UTF8ToString(fileExtension);
    6.     var unitycanvas = document.getElementById('unity-canvas');
    7.     if(!document.getElementById('UploadFileInput'))
    8.     {
    9.       var fileInput = document.createElement('input');
    10.       fileInput.setAttribute('type', 'file');
    11.       fileInput.setAttribute('id', 'UploadFileInput');
    12.       fileInput.setAttribute('accept', '.'+format);
    13.       fileInput.style.visibility = 'hidden';
    14.       fileInput.style.display = 'none';
    15.       fileInput.onclick = function (event)
    16.       {
    17.         this.value = null;
    18.         var element = document.getElementById('UploadFileInput');
    19.         element.parentNode.removeChild(element);
    20.         unitycanvas.removeEventListener('click', OpenFileDialog, false);
    21.       };
    22.       fileInput.onchange = function (event)
    23.       {
    24.         if(event.target.value != null)
    25.         {
    26.           var fn = event.target.files[0].name;
    27.           var ext = fn.substring(fn.lastIndexOf('.')+1, fn.length)
    28.           console.log('Filename: '+event.target.files[0].name+' / Extension: '+ext);
    29.           if(ext == format) SendMessage(gameObject, method, URL.createObjectURL(event.target.files[0]));
    30.           else console.log('File extension not allowed: '+ext);
    31.         }
    32.       };
    33.       document.body.appendChild(fileInput);
    34.     }
    35.     var OpenFileDialog = function()
    36.     {
    37.       document.getElementById('UploadFileInput').click();
    38.     };
    39.     unitycanvas.addEventListener('click', OpenFileDialog, false);
    40.   },
    41.   UploadTextureJsLib: function(gameObjectName, methodName, maxSize, imageFormat) {
    42.     var gameObject = UTF8ToString(gameObjectName);
    43.     var method = UTF8ToString(methodName);
    44.     var format = UTF8ToString(imageFormat);
    45.     var unitycanvas = document.getElementById('unity-canvas');
    46.     if(!document.getElementById('UploadTextureInput'))
    47.     {
    48.       var fileInput = document.createElement('input');
    49.       fileInput.setAttribute('type', 'file');
    50.       fileInput.setAttribute('id', 'UploadTextureInput');
    51.       if(format == "png")
    52.       {
    53.         fileInput.setAttribute('accept', '.png');
    54.       }
    55.       else
    56.       {
    57.         fileInput.setAttribute('accept', '.jpg, .jpeg, .png');
    58.       }
    59.       fileInput.style.visibility = 'hidden';
    60.       fileInput.style.display = 'none';
    61.       fileInput.onclick = function (event)
    62.       {
    63.         this.value = null;
    64.         var element = document.getElementById('UploadTextureInput');
    65.         element.parentNode.removeChild(element);
    66.         unitycanvas.removeEventListener('click', OpenFileDialog, false);
    67.       };
    68.       fileInput.onchange = function (event)
    69.       {
    70.         if(event.target.value != null)
    71.         {
    72.           var fn = event.target.files[0].name;
    73.           var ext = fn.substring(fn.lastIndexOf('.')+1, fn.length)
    74.           console.log('Filename: '+event.target.files[0].name+' / Extension: '+ext);
    75.           if((format == "png" && ext == format) || (format == "jpg" && (ext == format || ext == "jpeg" || ext == "png")))
    76.           {
    77.             format = ext;
    78.             if(maxSize > 0) resize_image(event.target.files[0])
    79.             else SendMessage(gameObject, method, URL.createObjectURL(event.target.files[0]));
    80.           }
    81.           else console.log('File extension not allowed: '+ext);
    82.         }
    83.       };
    84.       document.body.appendChild(fileInput);
    85.     }
    86.     var OpenFileDialog = function()
    87.     {
    88.       document.getElementById('UploadTextureInput').click();
    89.     };
    90.     unitycanvas.addEventListener('click', OpenFileDialog, false);
    91.  
    92.     //resize image function
    93.     function resize_image(file)
    94.     {
    95.       var reader = new FileReader();
    96.       reader.onloadend = function()
    97.       {
    98.         var tempImg = new Image();
    99.         tempImg.src = reader.result;
    100.         tempImg.onload = function()
    101.         {
    102.           var tempW = tempImg.width;
    103.           var tempH = tempImg.height;
    104.           if (tempW > tempH)
    105.           {
    106.             if (tempW > maxSize)
    107.             {
    108.               tempH *= maxSize / tempW;
    109.               tempW = maxSize;
    110.             }
    111.           }
    112.           else
    113.           {
    114.             if (tempH > maxSize)
    115.             {
    116.               tempW *= maxSize / tempH;
    117.               tempH = maxSize;
    118.             }
    119.           }
    120.           var dataURL = "";
    121.           var newBLOB = null;
    122.           try
    123.           {
    124.             if(document.getElementById('img-canvas')) document.getElementById('img-canvas').remove();
    125.             var canvas = document.createElement('canvas');
    126.             canvas.setAttribute('id', 'img-canvas');
    127.             canvas.width = tempW;
    128.             canvas.height = tempH;
    129.             var ctx = canvas.getContext("2d");
    130.             ctx.drawImage(this, 0, 0, tempW, tempH);
    131.             if(format == "png") dataURL = canvas.toDataURL("image/png");
    132.             else dataURL = canvas.toDataURL("image/jpeg");
    133.             function dataURItoBlob(dataURI)
    134.             {
    135.               var mime = dataURI.split(',')[0].split(':')[1].split(';')[0];
    136.               var binary = atob(dataURI.split(',')[1]);
    137.               var array = [];
    138.               for (var i = 0; i < binary.length; i++)
    139.               {
    140.                 array.push(binary.charCodeAt(i));
    141.               }
    142.               return new Blob([new Uint8Array(array)], {type: mime});
    143.             }
    144.             newBLOB = ((window.URL || window.webkitURL) || URL).createObjectURL(dataURItoBlob(dataURL));
    145.           }
    146.           catch(err)
    147.           {
    148.             alert('Error: ' + err.message);
    149.           }
    150.           finally
    151.           {
    152.             if(newBLOB === null) alert('Error: Empty URL...');
    153.             SendMessage(gameObject, method, newBLOB);
    154.           }
    155.         }//end tempImg.onload
    156.       }//end reader.onloadend
    157.       reader.readAsDataURL(file);
    158.     }//end resize_image
    159.   }//end UploadTexture
    160. };
    161. mergeInto(LibraryManager.library, UploadFilePlugin);

    Upload/Download scripts
    WebGLUpload.cs
    Code (CSharp):
    1. using System.Collections;
    2. using System.Runtime.InteropServices;
    3. using UnityEngine;
    4. using UnityEngine.Networking;
    5. using UnityEngine.UI;
    6.  
    7. public class WebGLUpload : MonoBehaviour
    8. {
    9.     public enum ImageFormat
    10.     {
    11.         jpg,
    12.         png
    13.     }
    14.     public enum FileExtension
    15.     {
    16.         zip,
    17.         myownformat
    18.     }
    19.     [DllImport("__Internal")]
    20.     private static extern void UploadFileJsLib(string gameObjectName, string methodName, string fileExtension);
    21.     [DllImport("__Internal")]
    22.     private static extern void UploadTextureJsLib(string gameObjectName, string methodName, int maxSize, string imageFormat);
    23.     private bool _nonReadable = true;
    24.     private Material _targetMaterial = null;
    25.     private Image _targetImage = null;
    26.  
    27.     /// <summary>
    28.     /// ___
    29.     /// <para>imageFormat -> Use "jpg" to allow jpg and png images. Use "png" if you need textures with alpha! (allow png only) you can edit the filter in the .jslib file</para>
    30.     /// <para>maxSize -> downsize large images. Max pixel size for the larger side (width or height, only for WebGL -> function in the .jslib) 0 = disabled</para>
    31.     /// <para>nonReadable -> should be "true" unless you have to edit the pixels (less memory usage)</para>
    32.     /// <para>targetMaterial -> set a material for the texture target. default = null</para>
    33.     /// <para>targetImage -> set a image for the texture target (it creates a sprite). default = null</para>
    34.     /// </summary>
    35.     public void UploadTexture(ImageFormat imageFormat, int maxSize, bool nonReadable, Material targetMaterial = null, Image targetImage = null)
    36.     {
    37.         _nonReadable = nonReadable;
    38.         _targetMaterial = targetMaterial;
    39.         _targetImage = targetImage;
    40. #if UNITY_EDITOR
    41.         string[] allImages = new string[] { "images", imageFormat.ToString() };
    42.         if (imageFormat == ImageFormat.jpg) allImages = new string[] { "jpg/png images", "png,jpg,jpeg" };
    43.         string path = UnityEditor.EditorUtility.OpenFilePanelWithFilters("Load a texture...", "", allImages);
    44.         //string path = UnityEditor.EditorUtility.OpenFilePanel("Load a texture...", "", imageFormat.ToString());
    45.         StartCoroutine(LoadTexture(path));
    46. #elif UNITY_WEBGL
    47.         UploadTextureJsLib(gameObject.name, "LoadTexture", maxSize, imageFormat.ToString());
    48. #endif
    49.     }
    50.  
    51.     /// <summary>
    52.     /// ___
    53.     /// <para>fileExtension -> Use your file extension "zip" e.g.</para>
    54.     /// <para>fileExtension -> Edit the enum values to add more extensions</para>
    55.     /// </summary>
    56.     public void UploadFile(FileExtension fileExtension)
    57.     {
    58. #if UNITY_EDITOR
    59.         string path = UnityEditor.EditorUtility.OpenFilePanel("Load a file...", "", fileExtension.ToString());
    60.         StartCoroutine(LoadFile(path));
    61. #elif UNITY_WEBGL
    62.         UploadFileJsLib(gameObject.name, "LoadFile", fileExtension.ToString());
    63. #endif
    64.     }
    65.  
    66.     //Load the texture from blob or from url. Called from the .jslib
    67.     private IEnumerator LoadTexture(string url)
    68.     {
    69.         using UnityWebRequest uwr = UnityWebRequestTexture.GetTexture(url, _nonReadable);
    70.         yield return uwr.SendWebRequest();
    71.         if (uwr.error != null) Debug.Log(uwr.error);
    72.         else
    73.         {
    74.             Texture2D texture = DownloadHandlerTexture.GetContent(uwr);
    75.             Debug.Log("Loaded texture size: " + texture.width + "x" + texture.height + "px" + " | URL: " + url);
    76.  
    77.             //apply the texture to a material or image
    78.             if (_targetMaterial) SetMaterialTexture(_targetMaterial, texture, false);
    79.             else if (_targetImage) _targetImage.sprite = Sprite.Create(texture, new Rect(0, 0, texture.width, texture.height), new Vector2(0.5f, 0.5f), 100f);
    80.             else
    81.             {
    82.                 //Do something with the texture...
    83.                 TextureResultExamples(texture);
    84.             }
    85.         }
    86.     }
    87.  
    88.     private void TextureResultExamples(Texture2D tex)
    89.     {
    90.         Debug.Log("unused texture here");
    91.     }
    92.  
    93.     //URP -> Set the material textures
    94.     public void SetMaterialTexture(Material mat, Texture2D tex, bool emissionInclusive)
    95.     {
    96.         mat.SetTexture("_BaseMap", tex);
    97.         if (emissionInclusive) mat.SetTexture("_EmissionMap", tex);
    98.     }
    99.  
    100.     //Load the byte[] from blob or from url. Called from the .jslib
    101.     private IEnumerator LoadFile(string url)
    102.     {
    103.         using UnityWebRequest uwr = UnityWebRequest.Get(url);
    104.         yield return uwr.SendWebRequest();
    105.         if (uwr.error != null) Debug.Log(uwr.error);
    106.         else
    107.         {
    108.             byte[] result = new byte[uwr.downloadHandler.data.Length];
    109.             System.Array.Copy(uwr.downloadHandler.data, 0, result, 0, uwr.downloadHandler.data.Length);
    110.             Debug.Log("Loaded file size: " + uwr.downloadHandler.data.Length + " bytes");
    111.  
    112.             //Do something with the byte array now...
    113.             ByteResultExamples(result);
    114.         }
    115.     }
    116.  
    117.     private void ByteResultExamples(byte[] result)
    118.     {
    119.         Debug.Log("unused file here");
    120.  
    121.         //Zip example (Zip / gzip Multiplatform Native Plugin from the asset store)
    122.         //----
    123.         //bool validZip = lzip.validateFile(null, result);
    124.         //if (validZip)
    125.         //{
    126.         //      bool exist = lzip.entryExists(null, "data/" + "myfile.dat", result);
    127.         //      if (exist)
    128.         //      {
    129.         //          byte[] fileBuffer = lzip.entry2Buffer(null, "data/" + "myfile.dat", result);
    130.         //          string myfileString = System.Text.Encoding.ASCII.GetString(fileBuffer);
    131.         //          fileBuffer = lzip.entry2Buffer(null, "tex/" + "mytexture.jpg", result);
    132.         //          Texture2D mytexture = new Texture2D(2, 2);
    133.         //          mytexture.LoadImage(fileBuffer);
    134.         //      }
    135.         //}
    136.  
    137.         //Texture2D example (if byte[] array from an image)
    138.         //----
    139.         //Texture2D tex = new Texture2D(2, 2);
    140.         //tex.LoadImage(result);
    141.     }
    142. }
    WebGLDownload.cs
    Code (CSharp):
    1. using System.Collections;
    2. using System.Runtime.InteropServices;
    3. using UnityEngine;
    4.  
    5. public class WebGLDownload : MonoBehaviour
    6. {
    7.     public enum ImageFormat
    8.     {
    9.         jpg,
    10.         png
    11.     }
    12.     private bool _isRecording = false;
    13.     [DllImport("__Internal")]
    14.     private static extern void DownloadFileJsLib(byte[] byteArray, int byteLength, string fileName);
    15.  
    16.     /// <summary>
    17.     /// ___
    18.     /// <para>bytes -> The bytes to be downloaded</para>
    19.     /// <para>fileName -> The downloaded file name (without extension)</para>
    20.     /// <para>fileExtension -> WebGLDownload.FileExtension.jpg/png/zip/</para>
    21.     /// </summary>
    22.     public void DownloadFile(byte[] bytes, string fileName, string fileExtension)
    23.     {
    24.         if (fileName == "") fileName = "UnnamedFile";
    25. #if UNITY_EDITOR
    26.         string path = UnityEditor.EditorUtility.SaveFilePanel("Save file...", "", fileName, fileExtension);
    27.         System.IO.File.WriteAllBytes(path, bytes);
    28.         Debug.Log("File saved: " + path);
    29. #elif UNITY_WEBGL
    30.         DownloadFileJsLib(bytes, bytes.Length, fileName + "." + fileExtension);
    31. #endif
    32.     }
    33.  
    34.     /// <summary>
    35.     /// ___
    36.     /// <para>imageFormat -> WebGLDownload.ImageFormat.jpg/png</para>
    37.     /// <para>screenshotUpscale -> Upscale the frame. default = 1</para>
    38.     /// <para>fileName -> Optional filename. Empty filename creates a name texture.width x texture.height in pixel + current datetime</para>
    39.     /// </summary>
    40.     public void GetScreenshot(ImageFormat imageFormat, int screenshotUpscale, string fileName = "")
    41.     {
    42.         if (!_isRecording) StartCoroutine(RecordUpscaledFrame(imageFormat, screenshotUpscale, fileName));
    43.     }
    44.  
    45.     IEnumerator RecordUpscaledFrame(ImageFormat imageFormat, int screenshotUpscale, string fileName)
    46.     {
    47.         _isRecording = true;
    48.         yield return new WaitForEndOfFrame();
    49.         try
    50.         {
    51.             if (fileName == "")
    52.             {
    53.                 int resWidth = Camera.main.pixelWidth * screenshotUpscale;
    54.                 int resHeight = Camera.main.pixelHeight * screenshotUpscale;
    55.                 string dateFormat = "yyyy-MM-dd-HH-mm-ss";
    56.                 fileName = resWidth.ToString() + "x" + resHeight.ToString() + "px_" + System.DateTime.Now.ToString(dateFormat);
    57.             }
    58.             Texture2D screenShot = ScreenCapture.CaptureScreenshotAsTexture(screenshotUpscale);
    59.             if (imageFormat == ImageFormat.jpg) DownloadFile(screenShot.EncodeToJPG(), fileName, "jpg");
    60.             else if (imageFormat == ImageFormat.png) DownloadFile(screenShot.EncodeToPNG(), fileName, "png");
    61.             Object.Destroy(screenShot);
    62.         }
    63.         catch (System.Exception e)
    64.         {
    65.             Debug.Log("Original error: " + e.Message);
    66.         }
    67.         _isRecording = false;
    68.     }
    69. }

    UnityPackage with the files attached
     

    Attached Files:

    Last edited: Sep 8, 2021
  3. Lemovision

    Lemovision

    Joined:
    Apr 6, 2020
    Posts:
    33
    Thanks for the scripts @sumpfkraut
    Works well on unity 2021.1

    In WebGLUpload.cs:
    "Use "jpg" to allow jpg and png images. Use "png" if you need textures with alpha! (allow png only) you can edit the filter in the .jslib file"

    Btw I only get the JPG type files also when setting format to "jpg"
    How to get both PNG and JPG available in the file open dialog?
    .jslib file seems fine and already set up to 'accept', '.jpg, .jpeg, .png'
    So I'm not sure why I get only JPG, any clue?
     
    Last edited: Sep 8, 2021
  4. sumpfkraut

    sumpfkraut

    Joined:
    Jan 18, 2013
    Posts:
    241
    you can try this
    Code (JavaScript):
    1. fileInput.setAttribute('accept', 'image/x-png, image/jpeg, image/jpg');
    instead of
    Code (JavaScript):
    1. fileInput.setAttribute('accept', '.'+format);
    you can also make a own extension "jpg_png" e.g. and do a if/else part in the .jslib file.
    if format == jpg_png, run the new code.
     
    Last edited: Sep 8, 2021
  5. Lemovision

    Lemovision

    Joined:
    Apr 6, 2020
    Posts:
    33
    Thanks yeah actually I got it that was just the behavior in UNITY_EDITOR in your script
    It does work in UNITY_WEBGL build when using the jslib file
    Maybe you could add the other types if format is JPG in WebGLUpload.cs too

    This line is direct imageFormat.ToString()
    Code (CSharp):
    1. #if UNITY_EDITOR
    2.         string path = UnityEditor.EditorUtility.OpenFilePanel("Load a texture...", "", imageFormat.ToString());
     
  6. sumpfkraut

    sumpfkraut

    Joined:
    Jan 18, 2013
    Posts:
    241
  7. Lemovision

    Lemovision

    Joined:
    Apr 6, 2020
    Posts:
    33
    So the updated WebGLUpload.cs code to match .jslib behavior in editor something like that is good?
    Maybe you can update your unitypackage for consistency in editor/build for other people also
    (I'm not a dev so I have no idea about proper code ^^)

    Code (CSharp):
    1. #if UNITY_EDITOR
    2.         string filters;
    3.         if (imageFormat.ToString() == "png") filters = "png";
    4.         else filters = "png,jpg,jpeg";
    5.         string path = UnityEditor.EditorUtility.OpenFilePanel("Load a texture...", "", filters);
    6.         StartCoroutine(LoadTexture(path));
    7. #elif UNITY_WEBGL
    8.         UploadTextureJsLib(gameObject.name, "LoadTexture", maxSize, imageFormat.ToString());
    EDIT: Btw I found out in "JPG" mode if the user loads a png with alpha it gets messed up a bit
    So in UploadFile.jslib I think it doesn't hurt to set it as PNG for every case

    Code (JavaScript):
    1. dataURL = canvas.toDataURL("image/png");
     
    Last edited: Sep 8, 2021
  8. sumpfkraut

    sumpfkraut

    Joined:
    Jan 18, 2013
    Posts:
    241
    I just changed the code in my post above.
    - The EditorUtility.OpenFilePanel Filter
    - The .jslib png problem

    btw. you can easy fix the .jslib png problem by adding one line after checking the file extension:
    format = ext;
    Code (CSharp):
    1. if(event.target.value != null)
    2.         {
    3.           var fn = event.target.files[0].name;
    4.           var ext = fn.substring(fn.lastIndexOf('.')+1, fn.length)
    5.           console.log('Filename: '+event.target.files[0].name+' / Extension: '+ext);
    6.           if((format == "png" && ext == format) || (format == "jpg" && (ext == format || ext == "jpeg" || ext == "png")))
    7.           {
    8.             format = ext;
    9.             if(maxSize > 0) resize_image(event.target.files[0])
    10.             else SendMessage(gameObject, method, URL.createObjectURL(event.target.files[0]));
    11.           }
    12.           else console.log('File extension not allowed: '+ext);
    13.         }
     
    Lemovision likes this.
  9. Pixelnovo

    Pixelnovo

    Joined:
    Sep 26, 2017
    Posts:
    23
    what about mobile devices compatibility to open the gallery?
     
    ju57m3 likes this.
  10. Lemovision

    Lemovision

    Joined:
    Apr 6, 2020
    Posts:
    33
    Yes I also noticed this problem, there's no window to open a file on mobile
    Do you have any idea how that could work @sumpfkraut

    Also on mobile the custom file extension save doesn't always work on some devices
    Sometimes it saves as .ext.txt, or as .png although I specified a specific .ext
     
  11. sumpfkraut

    sumpfkraut

    Joined:
    Jan 18, 2013
    Posts:
    241
    i have no experience developing on mobile devices ... sorry
    but it is quite possible that it will be different.

    that it saves with a wrong file extension, however, makes no sense to me
     
  12. Lemovision

    Lemovision

    Joined:
    Apr 6, 2020
    Posts:
    33
    So did anyone managed to have this work on android and ios?

    I noticed it's actually possible to test this and replicate the problem with Chrome devtools mobile view
    Seems like the PointerDown gets triggered with touch
    But releasing the touch I think doesn't trigger the click event in the javascript code?
    After that would the native Android/ios file browser show up?

    Is there any way to adapt this trick for mobile/touch input?
     
  13. thebuzzway47

    thebuzzway47

    Joined:
    Sep 23, 2020
    Posts:
    1
    Done all steps @sumpfkraut but still get error ( document.getElementById('canvas').addEventListener give null reference error unity)
    I Call the LoadFrom() funtion like .
    Picture1.png



    Kindly if somefull upload full project i need it. i spends days but same error.
    My Whole project is based on it .
     
  14. sumpfkraut

    sumpfkraut

    Joined:
    Jan 18, 2013
    Posts:
    241
  15. rdxtalha103

    rdxtalha103

    Joined:
    Aug 30, 2022
    Posts:
    14
    I tried this, but in my scenario I got the errors during build:
    Screenshot 2022-09-19 at 6.59.17 PM.png
     
  16. rdxtalha103

    rdxtalha103

    Joined:
    Aug 30, 2022
    Posts:
    14
    I got the following error, I have installed Python2.7, Unity version 2020.3.18f, MacOs version is Screenshot 2022-09-19 at 6.59.17 PM.png 12.6
     
  17. VIV-prod

    VIV-prod

    Joined:
    Aug 23, 2021
    Posts:
    4
    7 years later you saved another life ! Cheers !
     
  18. unity_A12A49FF530013E7B26

    unity_A12A49FF530013E7B26

    Joined:
    Dec 7, 2022
    Posts:
    7
    I know its been a year but can anyone tell me how to apply this on a button?
     
  19. sumpfkraut

    sumpfkraut

    Joined:
    Jan 18, 2013
    Posts:
    241
  20. unity_A12A49FF530013E7B26

    unity_A12A49FF530013E7B26

    Joined:
    Dec 7, 2022
    Posts:
    7
    woow from the creator! Thank you so much for sharing this. I really appreciate you.
    I tested out and it works for screenshot for the whole app! really good!
     
    Last edited: Dec 8, 2022