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. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice

Saving UI Image to file with transparent background

Discussion in 'Scripting' started by Notter, Dec 9, 2015.

  1. Notter

    Notter

    Joined:
    Mar 8, 2015
    Posts:
    65
    Hello, I need help in understand what i need to do to save an image properly.

    Right now i've manged to save my UI image, and then load it from file and into a sprite. but the problem is, the image that i take, also contains the background of the element i wanted to save.

    So what should i do in order to only show my character in the saved picture, without anything else?

    Right now this is how i save:

    Code (csharp):
    1. var tex =newTexture2D((int)width,(int)height,TextureFormat.RGB24,false);
    2. tex.ReadPixels(newRect(corners[0].x, corners[0].y, width, height),0,0);
     
  2. StarManta

    StarManta

    Joined:
    Oct 23, 2006
    Posts:
    8,744
    So you want to (for example) take a screenshot of the character to use in the UI?

    You'll have to use a Render Texture. Make a camera just for this task, assign a new Render Texture to it, and set its culling mask to render your character and nothing else. Make sure that the camera's clear flags are a solid color, and that the alpha on that is zero. In the UI, make a Raw Image component and assign this render texture to it.

    If you want a live-updating image, leave the camera enabled; if you just want one snapshot, call the camera's .Render when you want to snap it.
     
  3. Notter

    Notter

    Joined:
    Mar 8, 2015
    Posts:
    65
    Thanks for the answer, but I could use some more details since i got a bit confused
    I've hope I've followed your instructions properly, that's what i did so far:

    1. add 2nd camera to scene, set it to solidcolor with 0 alpha.
    2. created a new layer ("CaptureLayer"), and gave my UI image this layer, then set the new camera culling mask to only this layer.
    3. created a Render Texture and dragged it into the new camera.
    4. Add a Raw image (what does Raw image mean btw?) and placed it at the exact dimensions and position of my character image.
    5. dragged the Render Texture to the RawImage Texture (it became transparent).

    Now... what do i do to actually take the picture?
    I know how how to use the code i've pasted in my first post.
    but what will calling Render() on the new camera do? it returns void, so not sure what do to..

    (and yes, i just need a single snapshot)
    so so far, in code i got:
    1. enable 2nd camera
    2. Render()
    3. ???
    4. create Texture2D and readPixels.

    thanks again! :)
     
  4. StarManta

    StarManta

    Joined:
    Oct 23, 2006
    Posts:
    8,744
    The player is the thing that needs to be on the layer. The UI Image's layer doesn't matter for this purpose.

    The Image component expects a Sprite, imported and built to be efficiently rendered in the UI, but a Render Texture can't be a Sprite. The RawImage component expects any kind of Texture; it's less efficient than Image, graphically, but it's needed for a case like this.

    If you have the render texture assigned, then calling Render() will render what the camera says into that render texture.

    Using a render texture is an alternative to ReadPixels. Don't use a Texture2D at all - send the Render Texture anywhere you need it.
     
  5. Notter

    Notter

    Joined:
    Mar 8, 2015
    Posts:
    65
    Alright, that clears some things up. (and thanks for explaining raw image)

    but now you said:
    So to make it clear.. my character IS a UI image.
    If that's a problem, then i'll move it to a sprite on the camera..
    that's why i'm a bit confused about the cameras, since the cameras don't see the UI layer at all..

    And after I make the camera Render (and i'm guessing the camera component needs to be enabled for that)
    then i grab the texture from the RawImage and save that into file? (instead of ReadPixels)
    i'm guessing that's the purpose to if rawimage
     
  6. StarManta

    StarManta

    Joined:
    Oct 23, 2006
    Posts:
    8,744
    ....ok, somehow I completely misinterpreted what you were trying to do. Uh.... probably disregard a decent amount of what I said. I thought you needed to get a character image from game -> UI and were using the file as a means to do that. But you're actually trying to get UI -> file and the "game" is not even a factor.

    I am, at this point, curious why this is even an issue. If your character is the UI image, why do you need to save it out as an image? Don't you already have this image?

    I haven't tried using Render Textures with the UI in this way, but I think the camera should render the UI if you set the canvas to World Space?

    At that point, you'll have your Render Texture, and then you should be able to use ReadPixels to get it into a Texture2D, from which point you can save it to a PNG.
     
  7. Notter

    Notter

    Joined:
    Mar 8, 2015
    Posts:
    65
    Yeah I just had a bathroom break... and as you know, that's the time when you realize stuff.
    And i came back to say i'm a dummy, but you beat me to it XD

    My goal was to take a "snapshot" of some animation, then put it infront of a what my camera shows, and THEN save THAT to a file.
    And just like you said.. i can just check what's the current image in the animation, and use that..
    then in the end i'll use ReadPixels to get the camera box with the character inside.

    So.. yeah.. embarrassing.
    but I still learned a few things from you :)
    if i'll ever need to take a picture of an image with transparent background, i know i'll try to use Render Texture

    so thanks!
     
  8. The_Devil

    The_Devil

    Joined:
    Jun 6, 2015
    Posts:
    36
    @StarManta
    I tried what you said but the problem in my case is that the canvas is set to "Screen Space - Camera" as I need the canvas to scale as the device screen size. Because of this, the canvas is not visible in the second camera. Is there any way I could get this to work?
    Also, if I change the canvas to "World Space", when I set the layer of the images to "Player" and set the culling mask of the camera to "Player" nothing is visible. But if I set it to UI, all elements in the canvas are visible, including the image that needs to be saved.