【问题标题】:Unity c#, take screenshot and save to file as jpgUnity c#,截图并保存为jpg文件
【发布时间】:2014-12-01 04:04:40
【问题描述】:

我正在尝试截屏并将其保存到 jpg 格式的文件中。我正在关注这个例子。

http://docs.unity3d.com/ScriptReference/Texture2D.EncodeToPNG.html

这是我目前所拥有的:

    string jpgFile = Application.persistentDataPath + "/scrn-1.jpg";
    Texture2D tex = new Texture2D (Screen.width, Screen.height);
    tex.ReadPixels (new Rect(0, 0, Screen.width, Screen.height), 0, 0);
    tex.Apply ();
    var bytes = tex.EncodeToJPG();
    Destroy (tex);
    System.IO.File.WriteAllBytes(jpgFile, bytes);

我发现在 iOS 上的 Unity 中运行它会给我:

JPEG 参数结构不匹配:库认为大小为 372,调用者预期为 360

但是,如果我将转换更改为 tex.EncodeToPNG();并将文件名更改为 .png 一切正常。我不确定如何进行任何帮助将不胜感激。谢谢。

【问题讨论】:

  • 你也试过Game Dev Exchange吗?
  • 我没有。我会尽快在那里复制一份。谢谢。
  • 您已将其标记为“ios”,因此我假设您正在运行某种类型的 Apple 手持设备。您是否尝试过同时按下主页和电源按钮? ;)
  • 哈哈,我需要能够以编程方式完成所有工作。我将在生成此图像文件后将其传递给 Android 和 iOS 本机代码。感谢您的输入。我将添加另一个标签。
  • 我假设 Unity 是针对 libjpeg 动态构建的,如果是这种情况,在 Unity 发布修复程序之前问题不会解决(您是最新的吗?)。另外,您不能使用 .png 有什么原因吗?

标签: c# android ios unity3d texture2d


【解决方案1】:

我找到了this,您可以将其保存为 .jpg。我通常只使用capture screen 并另存为.png。

给你:

using UnityEngine;
using System.Collections;

public class HiResScreenShots : MonoBehaviour {
    public int resWidth = 2550; 
    public int resHeight = 3300;

    private bool takeHiResShot = false;

    public static string ScreenShotName(int width, int height) {
        return string.Format("{0}/screenshots/screen_{1}x{2}_{3}.png", 
                             Application.dataPath, 
                             width, height, 
                             System.DateTime.Now.ToString("yyyy-MM-dd_HH-mm-ss"));
    }

    public void TakeHiResShot() {
        takeHiResShot = true;
    }

    void LateUpdate() {
        takeHiResShot |= Input.GetKeyDown("k");
        if (takeHiResShot) {
            RenderTexture rt = new RenderTexture(resWidth, resHeight, 24);
            camera.targetTexture = rt;
            Texture2D screenShot = new Texture2D(resWidth, resHeight, TextureFormat.RGB24, false);
            camera.Render();
            RenderTexture.active = rt;
            screenShot.ReadPixels(new Rect(0, 0, resWidth, resHeight), 0, 0);
            camera.targetTexture = null;
            RenderTexture.active = null; // JC: added to avoid errors
            Destroy(rt);
            byte[] bytes = screenShot.EncodeToPNG();
            string filename = ScreenShotName(resWidth, resHeight);
            System.IO.File.WriteAllBytes(filename, bytes);
            Debug.Log(string.Format("Took screenshot to: {0}", filename));
            takeHiResShot = false;
        }
    }
}

如果您只想要任何类型的图片,我强烈推荐:

using UnityEngine;
using System.Collections;

public class ExampleClass : MonoBehaviour 
{
    void OnMouseDown() 
    {
        Application.CaptureScreenshot("Screenshot.png");
    }
}

简单有效。

【讨论】:

  • 感谢您的回复。您提供的第二个示例是我最初使用的示例。然后将捕获的文件保存为 jpg 变得很重要。您会注意到,在您提供的第一个示例中,当我们将 Texture2D 转换为 byte[] 时,我们调用 EncodeToPNG();不幸的是,这段代码仍然将文件保存为 png。我遇到的问题是调用 Texture2d 的姊妹函数 EncodeToJPG() 给了我上面看到的错误。不过感谢您的帖子:)
【解决方案2】:

我今天实际上需要这样的东西,但没有保存它。 Unity 没有为我们提供将图像立即作为字节返回的默认方法,这就是我解决问题的方法。

internal class ScreenCapture : MonoBehaviour
{
    internal byte[] Image = null;

    internal void SaveScreenshot()
    {
        StartCoroutine(SaveScreenshot_ReadPixelsAsynch());
    }

    private IEnumerator SaveScreenshot_ReadPixelsAsynch()
    {
        //Wait for graphics to render
        yield return new WaitForEndOfFrame();

        //Create a texture to pass to encoding
        Texture2D texture = new Texture2D(Screen.width, Screen.height, TextureFormat.RGB24, false);

        //Put buffer into texture
        texture.ReadPixels(new Rect(0, 0, Screen.width, Screen.height), 0, 0);

        //Split the process up--ReadPixels() and the GetPixels() call inside of the encoder are both pretty heavy
        yield return 0;

        byte[] bytes = texture.EncodeToPNG();
        Image = bytes;

        //Tell unity to delete the texture, by default it seems to keep hold of it and memory crashes will occur after too many screenshots.
        DestroyObject(texture);
    }
}

用法:

internal static ScreenCapture Capture;



if (Capture == null)
{
    Capture = Camera.main.gameObject.AddComponent<ScreenCapture>();
}
Capture.SaveScreenshot();

// if you wish to save:
System.IO.File.WriteAllBytes("filename.png", Capture.Image);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-12-16
    • 2014-02-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-10
    • 1970-01-01
    相关资源
    最近更新 更多