从Unity ARCore将AcquireCameraImageBytes()保存为图像存储 [英] Save AcquireCameraImageBytes() from Unity ARCore to storage as an image

查看:405
本文介绍了从Unity ARCore将AcquireCameraImageBytes()保存为图像存储的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用统一性和新的ARCore 1.1版,该API公开了一些获取相机信息的新方法.但是,我找不到将其另存为jpg格式的本地文件的好例子.

Using unity, and the new 1.1 version of ARCore, the API exposes some new ways of getting the camera information. However, I can't find any good examples of saving this as a file to local storage as a jpg, for example.

ARCore示例中有一个很好的示例,可以检索相机数据,然后在此处进行一些处理:

The ARCore examples have a nice example of retrieving the camera data and then doing something with it here: https://github.com/google-ar/arcore-unity-sdk/blob/master/Assets/GoogleARCore/Examples/ComputerVision/Scripts/ComputerVisionController.cs#L212 and there are a few examples of retrieving the camera data in that class, but nothing around saving that data.

我已经看过:如何服用&使用Unity ARCore SDK保存图片/屏幕截图?,它使用较旧的API来获取数据,并且在保存方面也没有详细介绍.

I've seen this: How to take & save picture / screenshot using Unity ARCore SDK? which uses the older API way of getting data, and doesn't really go into detail on saving, either.

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

What I ideally want is a way to turn the data from Frame.CameraImage.AcquireCameraImageBytes() in the API into a stored jpg on disk, through Unity.

更新

此后,我主要通过在ARCore github页面上深入研究此问题来使其起作用:

I've since got it working mainly through digging through this issue on the ARCore github page: https://github.com/google-ar/arcore-unity-sdk/issues/72#issuecomment-355134812 and modifying Sonny's answer below, so it's only fair that one gets accepted.

如果其他任何人都想这样做,我必须执行以下步骤:

In case anyone else is trying to do this I had to do the following steps:

  1. 向Start方法添加回调,以在图像可用时运行OnImageAvailable方法:

public void Start()
{
    TextureReaderComponent.OnImageAvailableCallback += OnImageAvailable;
}

  • 将TextureReader(来自SDK随附的计算机视觉示例)添加到相机和脚本中

  • Add a TextureReader (from the computer vision example provided with the SDK) to your camera and your script

    您的OnImageAvailable应该看起来像这样:

    Your OnImageAvailable should look a bit like this:

    /// <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中,应该可以将原始图像数据加载到纹理中,然后使用

    In Unity, it should be possible to load the raw image data into a texture and then save it to a JPG using UnityEngine.ImageConversion.EncodeToJPG. Example code:

    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.)请参见 TextureFormat 上的Unity文档.以及它是否与ARCore的ImageFormatType兼容.

    However, I'm not sure if the TextureFormat corresponds to a format that works with Frame.CameraImage.AcquireCameraImageBytes(). (I'm familiar with Unity but not ARCore.) See Unity's documentation on TextureFormat, and whether that is compatible with ARCore's ImageFormatType.

    还要测试代码对于您的应用程序是否足够性能.

    Also, test whether the code is performant enough for your application.

    如用户@Lece所述,请使用File.WriteAllBytes保存编码数据.我已经更新了上面的代码示例,因为我最初省略了该步骤.

    As user @Lece explains, save the encoded data with File.WriteAllBytes. I've updated my code example above as I omitted that step originally.

    编辑#2:有关ARCore的完整答案,请参阅问题帖的更新.此处的注释也可能有用-Jordan指定主要部分是使用

    EDIT #2: For the complete answer specific to ARCore, see the update to the question post. The comments here may also be useful - Jordan specified that "the main part was to use the texture reader from the computer vision sdk example here".

    这篇关于从Unity ARCore将AcquireCameraImageBytes()保存为图像存储的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆