Unity로 저장할 때 알파 부분이 어두워지는 문제 포획

12707 단어 screencaptureUnityiOS
※ 본 기사는 맥과 iOS를 통해 수행 및 동작 확인.Windows의 상태는 확인되지 않았습니다.

유닛으로 화면 포착하는 방법.


Unity 묘사를 캡처하려는 섹션이 PNG에 저장됩니다.
그때는 드물지만 알파를 저장하고 싶은 값이 있었어요.
우선 검색하기 좋은 방법을 쓰세요.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.IO;

public class ScreenCapture : MonoBehaviour
{
    void Update()
    {
        if (Input.GetKeyDown(KeyCode.Space))
        {
            StartCoroutine(captureScreen("test.png"));
        }
    }

    IEnumerator captureScreen(string filename)
    {
        yield return new WaitForEndOfFrame();

        //  キャプチャ用Texture2Dを作る
        var captureTex = new Texture2D(Screen.width, Screen.height, TextureFormat.ARGB32, false);

        //  ReadPixel
        captureTex.ReadPixels(new Rect(0, 0, Screen.width, Screen.height), 0, 0);
        captureTex.Apply();

        //  pngデータ取得
        byte[] pngData = captureTex.EncodeToPNG();

        //  破棄
        Destroy(captureTex);

        //  ファイルに保存
        var filePath = Path.Combine(Application.persistentDataPath, filename);
        File.WriteAllBytes(filePath, pngData);
        Debug.Log("captured : " + filePath);
    }
}

스페이스바를 사용하여 카메라에 이 스크립트를 찍을 수 있습니다.
알파의 값을 이용했기 때문에 카메라의 배경은 투명하다.
카메라가 하나면 SolidColor로 색상을 채운 알파로 0을 만듭니다.
캡처 테스트를 하려면 먼저 상황을 파악해야 하고, 유니티 에디터의 화면을 OS의 캡처로 촬영한 화면도 미리 업로드해야 한다.

검은색 부분은 SolidColor이고 RGBA는 모두 0 상태입니다.
아래 화이트 플랜트는 unlit/color로 화이트로 되어 있어 완전 화이트입니다.
위에 앉은 큐브의 안쪽은 불투명하고 바깥쪽은 반투명하다.
이상 프로그램에서 캡처한 결과가 이거예요.
※ 참고로 저장된 서류가 맥인 경우~/Library/Caches/<PlayerSettingsのCompanyName>/<Project名>/.

배경색은 알파0으로 잘 변한 것 같은데 이상한 점이 있어요.
가장자리가 까매졌다.이것은 톱니 저항에 따라 알파를 붙였는데 그 부분은 안 좋은 것 같아요.
입방체의 반투명 부분도 배경과 흰색 부분이 중첩될 때 어두워진다.

원인 및 해결 방법


이 가능하다, ~할 수 있다,...ReadPixel이라고 부르면 Priemultiplied 알파의 색상 정보가 돌아오기 때문이라고 생각합니다.(대개 Windows의 경우는 어떻습니까?)
Premiultiplied이므로 RGB 값 앞에 알파 값을 추가했습니다.미리 걸려있는 것이기 때문에 가벼워지는 것 같은 것을 처리하고, PNG에 그대로 보관하면 알파가 1보다 작은 곳에서 색이 어두워진다.
그래서 저장하기 전에 알파치로 깨면 될 것 같아요.
코드.
IEnumerator captureScreen(string filename)
{
    yield return new WaitForEndOfFrame();

    //  キャプチャ用Texture2Dを作る
    var captureTex = new Texture2D(Screen.width, Screen.height, TextureFormat.ARGB32, false);

    //  ReadPixel
    captureTex.ReadPixels(new Rect(0, 0, Screen.width, Screen.height), 0, 0);
    captureTex.Apply();

    //  色を直す(PremultipliedAlphaなので戻す)
    var colors = captureTex.GetPixels(0, 0, captureTex.width, captureTex.height);
    for (int y = 0; y < captureTex.height; y++)
    {
        for (int x = 0; x < captureTex.width; x++)
        {
            Color c = colors[captureTex.width * y + x];
            if(c.a > 0.0f) 
            {
                c.r /= c.a;
                c.g /= c.a;
                c.b /= c.a;
                colors[captureTex.width * y + x] = c;
            }
        }
    }
    captureTex.SetPixels(colors);
    captureTex.Apply();

    //  pngデータ取得
    byte[] pngData = captureTex.EncodeToPNG();

    //  破棄
    Destroy(captureTex);

    //  ファイルに保存
    var filePath = Path.Combine(Application.persistentDataPath, filename);
    File.WriteAllBytes(filePath, pngData);
    Debug.Log("captured : " + filePath);
}
저장하기 전에 GetPixels로 색을 얻고 픽셀별 색을 변경한 후 SetPixels로 반환합니다.
이 코드로 촬영한 결과는 다음과 같다.

검은색 테두리가 없어지면 배경백과 평면백의 차이도 사라진다!
그래서 검색해도 정보가 없으니 먼저 적어 놓으세요.

좋은 웹페이지 즐겨찾기