c# - 从Unity ARCore将AcquireCameraImageBytes()保存为图像存储

原文 标签 c# android unity3d arcore

通过使用统一性和ARCore的新1.1版本,该API公开了一些获取相机信息的新方法。但是,我找不到将其作为文件另存为jpg的任何很好的示例。

ARCore示例提供了一个很好的示例,可以检索摄像机数据,然后在此处进行一些处理:https://github.com/google-ar/arcore-unity-sdk/blob/master/Assets/GoogleARCore/Examples/ComputerVision/Scripts/ComputerVisionController.cs#L212,并且有一些示例可以检索该类中的摄像机数据,但是保存该数据方面没有任何事。

我已经看到了这一点:How to take & save picture / screenshot using Unity ARCore SDK?使用较旧的API来获取数据,并且在保存方面也没有详细介绍。

我理想中想要的是一种通过Unity将数据从API中的Frame.CameraImage.AcquireCameraImageBytes()转换为磁盘上存储的jpg的方法。

更新

从那以后,我主要通过在ARCore github页面上研究此问题来工作:https://github.com/google-ar/arcore-unity-sdk/issues/72#issuecomment-355134812并在下面修改Sonny的答案,因此只有一个人被接受才是公平的。

万一有其他人试图这样做,我必须执行以下步骤:

  • 在图像可用时,将回调添加到Start方法以运行OnImageAvailable方法:
    public void Start()
    {
        TextureReaderComponent.OnImageAvailableCallback += OnImageAvailable;
    }
    
  • 将TextureReader(来自SDK附带的计算机视觉示例)添加到相机和脚本
  • 您的OnImageAvailable应该看起来像这样:
    /// <summary>
    /// Handles a new CPU image.
    /// </summary>
    /// <param name="format">The format of the image.</param>
    /// <param name="width">Width of the image, in pixels.</param>
    /// <param name="height">Height of the image, in pixels.</param>
    /// <param name="pixelBuffer">Pointer to raw image buffer.</param>
    /// <param name="bufferSize">The size of the image buffer, in bytes.</param>
    private void OnImageAvailable(TextureReaderApi.ImageFormatType format, int width, int height, IntPtr pixelBuffer, int bufferSize)
    {
        if (m_TextureToRender == null || m_EdgeImage == null || m_ImageWidth != width || m_ImageHeight != height)
        {
            m_TextureToRender = new Texture2D(width, height, TextureFormat.RGBA32, false, false);
            m_EdgeImage = new byte[width * height * 4];
            m_ImageWidth = width;
            m_ImageHeight = height;
        }
    
        System.Runtime.InteropServices.Marshal.Copy(pixelBuffer, m_EdgeImage, 0, bufferSize);
    
        // Update the rendering texture with the sampled image.
        m_TextureToRender.LoadRawTextureData(m_EdgeImage);
        m_TextureToRender.Apply();
    
        var encodedJpg = m_TextureToRender.EncodeToJPG();
        var path = Application.persistentDataPath;
    
        File.WriteAllBytes(path + "/test.jpg", encodedJpg);
    }
    
  • 最佳答案

    在Unity中,应该可以将原始图像数据加载到纹理中,然后使用UnityEngine.ImageConversion.EncodeToJPG将其保存为JPG。示例代码:

    public class Example : MonoBehaviour
    {
        private Texture2D _texture;
        private TextureFormat _format = TextureFormat.RGBA32;
    
        private void Awake()
        {
            _texture = new Texture2D(width, height, _format, false);
        }
    
        private void Update()
        {
            using (var image = Frame.CameraImage.AcquireCameraImageBytes())
            {
                if (!image.IsAvailable) return;
    
                // Load the data into a texture 
                // (this is an expensive call, but it may be possible to optimize...)
                _texture.LoadRawTextureData(image);
                _texture.Apply();
            }
        }
    
        public void SaveImage()
        {
            var encodedJpg = _texture.EncodeToJPG();
            File.WriteAllBytes("test.jpg", encodedJpg)
        }
    }
    

    但是,我不确定TextureFormat是否对应于Frame.CameraImage.AcquireCameraImageBytes()可以使用的格式。 (我熟悉Unity,但不熟悉ARCore。)请参阅Unity的TextureFormat文档,以及该文档是否与ARCore的ImageFormatType兼容。

    另外,测试代码对于您的应用程序是否足够性能。

    编辑:正如用户@Lece解释的那样,将编码后的数据保存为File.WriteAllBytes。我已经更新了上面的代码示例,因为我最初省略了该步骤。

    编辑#2:有关特定于ARCore的完整答案,请参阅问题帖的更新。这里的注释也可能有用-Jordan指定“主要部分是使用computer vision sdk example here中的纹理读取器”。

    关于c# - 从Unity ARCore将AcquireCameraImageBytes()保存为图像存储,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49579334/

    相关文章:

    c# - 我向后走时第三人称相机口吃

    c# - MongoDB 使用 C# 驱动程序根据数组中的第 N 个值更新多条记录

    c# - C#中的目录不为空错误

    android - 是否可以在Android中使用写入C代码访问rild套接字

    android - Android ZXing获取条形码图像

    c# - 在Visual Studio中,我的方法名称为蓝色,而不是白色

    android - 提高太多UI图像的帧速率-Unity UI

    c# - .dll引用已在 Debug模式下正确加载到C#项目中,但在Release中找不到 namespace

    c# - 扩展方法和GetBytes实现

    java - Java6中java.nio.file.Paths的替代方法