1
\$\begingroup\$

Current render result:

enter image description here

When I am rendering image in Unity and saving as file(.png), quality of those files are reduced. They become tiny and very poor.

How can I enhance that?

Dimension of the image file is 269*168.

Code to save image :

using UnityEngine;
using System.IO;
using System;

//getty code
public class Capture : MonoBehaviour
{
    private static int resWidth = 3840;
    private static int resHeight = 2160;
    private static GameObject camObj = null;


    public static string ScreenShotName()
    {
        return string.Format("{0}/screenshots/{1}.png",
                             Application.dataPath,
                             Util.name_);
    }

    void Start()
    {
        camObj = gameObject;
        Directory.CreateDirectory(Application.dataPath + "/screenshots");
        resHeight=GetComponent<Camera>().pixelHeight;
        resWidth=GetComponent<Camera>().pixelWidth;
        //Util.everyThingHot = true;
    }

    public static void TakeHiResShot()
    {
        try
        {
            RenderTexture rt = new RenderTexture(resWidth, resHeight, 24);
            camObj.GetComponent<Camera>().targetTexture = rt;

            Texture2D screenShot = new Texture2D(resWidth, resHeight, TextureFormat.RGB24, false);
            camObj.GetComponent<Camera>().Render();
            RenderTexture.active = rt;
            screenShot.ReadPixels(new Rect(0, 0, resWidth, resHeight), 0, 0);
            camObj.GetComponent<Camera>().targetTexture = null;
            RenderTexture.active = null;
            Destroy(rt);
            byte[] bytes = screenShot.EncodeToPNG();
            string filename = ScreenShotName();
            File.WriteAllBytes(filename, bytes);
            Debug.Log(string.Format("Took screenshot to: {0}", filename));
            bytes = null;
        }
        catch(Exception e)
        {
            Debug.Log("Error");
        }

    }

}

Sample:

image sample

What I see during saving shot:

enter image description here

It's taking a lot CPU,GPU resources, renders correctly but doesn't give me what I want as a file

\$\endgroup\$
  • 1
    \$\begingroup\$ Can you show us a screenshot of what you see in Unity before you save the png? We need to see how the saved file differs from your in-game rendering to know what we're trying to fix here. \$\endgroup\$ – DMGregory May 7 at 13:19
  • 1
    \$\begingroup\$ It looks like the camera might have a smaller pixel width & pixel height than you'd expected. Have you tried setting the width & height to known values instead of reading them from the camera? \$\endgroup\$ – DMGregory May 7 at 13:41
  • \$\begingroup\$ Yes I have also tried that, changed height,width manually, it is in the first lines of the class. \$\endgroup\$ – Maifee Ul Asad May 7 at 14:54
  • 1
    \$\begingroup\$ In the code shown here, you're overwriting those values in Start, so they're not kept, that's why I had to ask if you'd tried not overwriting them in Start. \$\endgroup\$ – DMGregory May 7 at 15:33
  • 1
    \$\begingroup\$ If you've solved your problem, please feel free to post your solution as an Answer. \$\endgroup\$ – DMGregory May 7 at 16:08
0
\$\begingroup\$

The problem was I was changing the value of resHeight and resWidth as @DMGregory mentioned. So it was rendering in poor quality.

Now,

using UnityEngine;
using System.IO;
using System;

//getty code
public class Capture : MonoBehaviour
{
private static int resWidth = 3840;
private static int resHeight = 2160;
private static GameObject camObj = null;


public static string ScreenShotName()
{
    return string.Format("{0}/screenshots/{1}.png",
                         Application.dataPath,
                         Util.name_);
}

void Start()
{
    camObj = gameObject;
    Directory.CreateDirectory(Application.dataPath + "/screenshots");
    //resHeight=GetComponent<Camera>().pixelHeight; *Line changed*
    //resWidth=GetComponent<Camera>().pixelWidth; *Line changed*
    //Util.everyThingHot = true;
}

public static void TakeHiResShot()
{
    try
    {
        RenderTexture rt = new RenderTexture(resWidth, resHeight, 24);
        camObj.GetComponent<Camera>().targetTexture = rt;

        Texture2D screenShot = new Texture2D(resWidth, resHeight, TextureFormat.RGB24, false);
        camObj.GetComponent<Camera>().Render();
        RenderTexture.active = rt;
        screenShot.ReadPixels(new Rect(0, 0, resWidth, resHeight), 0, 0);
        camObj.GetComponent<Camera>().targetTexture = null;
        RenderTexture.active = null;
        Destroy(rt);
        byte[] bytes = screenShot.EncodeToPNG();
        string filename = ScreenShotName();
        File.WriteAllBytes(filename, bytes);
        Debug.Log(string.Format("Took screenshot to: {0}", filename));
        bytes = null;
    }
    catch(Exception e)
    {
        Debug.Log("Error");
    }

}

}

Now everything renders perfectly in 4K.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.