Search Unity

Question Unity Texture 2D from Uint64List byte[]

Discussion in 'Scripting' started by RoyalCoder, Jul 28, 2022.

  1. RoyalCoder

    RoyalCoder

    Joined:
    Oct 4, 2013
    Posts:
    301
    I'm trying to generate a 2D texture from Uint64List bytes tried in a lot of ways, but nothing works :(

    1. I'm getting the byte data from Image on my website like that:
    Code (CSharp):
    1. final ByteData data =
    2. await NetworkAssetBundle(Uri.parse(lastPosts.docs[0]['mediaUrl'][0]))
    3.     .load(lastPosts.docs[0]['mediaUrl'][0]);
    4. final Uint64List bytes = data.buffer.asUint64List();
    2. Sending and receiving in Unity as a string and trying to generate a texture from byte data unsuccessfully, this way:
    Code (CSharp):
    1.  if (!string.IsNullOrEmpty(fl_data))
    2.             {
    3.                 byte[] imgBytes = Encoding.UTF8.GetBytes(fl_data); //Encoding.ASCII.GetBytes (inputString);
    4.                 Texture2D tex = new Texture2D(512, 512, TextureFormat.ARGB32, false);
    5.                 tex.LoadRawTextureData(imgBytes);
    6.                 tex.Apply();
    7.  
    8.                 m_screenTexture.texture = tex;
    9.             }
    or

    Code (CSharp):
    1.  
    2.             byte[] imgByte = Encoding.UTF32.GetBytes(fl_data);
    3.             byte[] imgBytes2 = Convert.FromBase64String(fl_data);
    I'm lost somebody can help me please, thanks in advance!
     
  2. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,689
    Start debugging what the data looks like, printing it all out with Debug.Log(), checking that it is the same. Make a tiny micro 1x1 pixel image so you can reason if the data on the website is identical in every way to what you are receiving.

    You must find a way to get the information you need in order to reason about what the problem is.

    What is often happening in these cases is one of the following:

    - the code you think is executing is not actually executing at all
    - the code is executing far EARLIER or LATER than you think
    - the code is executing far LESS OFTEN than you think
    - the code is executing far MORE OFTEN than you think
    - the code is executing on another GameObject than you think it is
    - you're getting an error or warning and you haven't noticed it in the console window

    To help gain more insight into your problem, I recommend liberally sprinkling Debug.Log() statements through your code to display information in realtime.

    Doing this should help you answer these types of questions:

    - is this code even running? which parts are running? how often does it run? what order does it run in?
    - what are the values of the variables involved? Are they initialized? Are the values reasonable?
    - are you meeting ALL the requirements to receive callbacks such as triggers / colliders (review the documentation)

    Knowing this information will help you reason about the behavior you are seeing.

    You can also supply a second argument to Debug.Log() and when you click the message, it will highlight the object in scene, such as
    Debug.Log("Problem!",this);


    If your problem would benefit from in-scene or in-game visualization, Debug.DrawRay() or Debug.DrawLine() can help you visualize things like rays (used in raycasting) or distances.

    You can also call Debug.Break() to pause the Editor when certain interesting pieces of code run, and then study the scene manually, looking for all the parts, where they are, what scripts are on them, etc.

    You can also call GameObject.CreatePrimitive() to emplace debug-marker-ish objects in the scene at runtime.

    You could also just display various important quantities in UI Text elements to watch them change as you play the game.

    If you are running a mobile device you can also view the console output. Google for how on your particular mobile target, such as this answer or iOS: https://forum.unity.com/threads/how-to-capturing-device-logs-on-ios.529920/ or this answer for Android: https://forum.unity.com/threads/how-to-capturing-device-logs-on-android.528680/

    Another useful approach is to temporarily strip out everything besides what is necessary to prove your issue. This can simplify and isolate compounding effects of other items in your scene or prefab.

    Here's an example of putting in a laser-focused Debug.Log() and how that can save you a TON of time wallowing around speculating what might be going wrong:

    https://forum.unity.com/threads/coroutine-missing-hint-and-error.1103197/#post-7100494

    Networking, UnityWebRequest, WWW, Postman, curl, WebAPI, etc:

    https://forum.unity.com/threads/using-unity-for-subscription-lists.1070663/#post-6910289

    https://forum.unity.com/threads/unity-web-request-acting-stupid.1096396/#post-7060150

    And setting up a proxy can be very helpful too, in order to compare traffic:

    https://support.unity.com/hc/en-us/articles/115002917683-Using-Charles-Proxy-with-Unity
     
    RoyalCoder likes this.
  3. Bunny83

    Bunny83

    Joined:
    Oct 18, 2010
    Posts:
    3,990
    I guess Uint64List is the dart type? This has nothing to do with Unity as this would probably be server-side. So the first thing you have to clear up is how that int 64 list actually translates to bytes. Over the network you actually receive octets (bytes) so you have to make sure they are actually send out in the right order. Why do you even use a list of int64 values? Shouldn't there be a way to actually get a list of bytes?

    Second, "bytes" are not an image format. Literally any image format can be represented with bytes. So if and how you may need to load the data depends on the actual format of the data.

    Third, why do you use utf8 decoding? If it's binary data that you receive, it should be bytes in the first place. The UTF8 decoding of a string will in most cases not represent the correct data, at all. You only showed tiny snippets with a lot important details in between missing.

    Finally "LoadRawTextureData" expects an image in the raw format that the GPU uses, not any consumer image formats like png, jpg, bmp, or whatever. In your case the data has to directly represent ARGB data. Without more details on how you actually send out the data and how you receive it on the Unity side we can't really help you. Also up to this point we don't know what your "data" variable on your server actually contains, does it contain uncompressed ARGB data?
     
    RoyalCoder likes this.
  4. RoyalCoder

    RoyalCoder

    Joined:
    Oct 4, 2013
    Posts:
    301

    @Kurt-Dekker thanks a lot!
    @Bunny83 thanks for your answer!

    Yes, it's Dart :p, so basically I'm getting the ByteData like that:

    Code (CSharp):
    1.     ByteData data = ByteData(100);
    2.  
    3.       data = await NetworkAssetBundle(Uri.parse(path)).load(path);
    4.  
    5.  
    6.     ui.Codec codec = await ui.instantiateImageCodec(data.buffer.asUint8List(),
    7.         targetWidth: width);
    8.  
    9.  
    In Flutter it's ok, after that I'm sending these bytes as string to Unity, it's possible to decode the string back to byte[] to generate the texture? I'm a little bit confused here about how to achieve this, thanks!
     
  5. Bunny83

    Bunny83

    Joined:
    Oct 18, 2010
    Posts:
    3,990
    You haven't really answered my questions, but according to instantiateImageCodec the "list" contains the binary data of an actual image format like png / jpg / gif. So the data can not be read into "LoadRawTextureData" as it expects uncompressed raw ARGB data. You can use LoadImage to actually load an image format. Note that Unity does only support a few image formats at runtime. The Unity editor does support much more image formats. At runtime you should use either png or jpg.

    However we still don't know how you actually receive the data. Don't you use a UnityWebRequest? What download handler do you use? Usually you would directly use a DownloadHandlerTexture as it directly decodes the image into a texture for you.

    It's up to you to provide relevant code and to explain your situation as clear as possible. You also should be aware what kind of data you're dealing with. We can't possibly know this, it is your code and we've only seen a few lines of it ^^.
     
    RoyalCoder likes this.