Unity3D中,我需要从C++的DLL中获取摄像头取得的图像数据(uchar
*),并且用Rawimage显示出来。
程序包括C++的DLL接口部分和Unity3D C#的接口部分。
使用VS 2015建立一个空白的Visual C++ Win32控制台应用程序,使用.NET
Framework 4.7.2,应用程序类型为DLL。
C++ CameraDll.cpp:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 #include "Camera.h" #define DLLExport __declspec(dllexport) extern "C" { DLLExport Camera* CreateCamera(int width, int height, int fps) { Camera* obj = new Camera(width, height, fps); return obj; } DLLExport void DestroyCamera(Camera* obj) { delete obj; obj = NULL; } DLLExport bool GetImage(Camera* obj, unsigned char *& data, int &size) { return obj->GetImage(data, size); } }
C++ Camera.cpp:
1 2 3 4 5 6 7 8 ... bool Camera::GetImage(unsigned char*& rgb24_pixels, int& size) { ... rgb24_pixels = img.data; size = img.cols * img.rows * img.channels(); return true; } ...
编译Release
x64后,将dll文件放到Unity项目的Assets\Plugins
文件夹中。Unity中建立Create
Empty对象,添加一个脚本Camera.cs
。
C# Camera.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 using System; using System.Collections; using System.Collections.Generic; using System.IO; using UnityEngine; using UnityEngine.UI; using System.Runtime.InteropServices; public class Camera : MonoBehaviour { [DllImport("Camera")] private static extern IntPtr CreateCamera(int width, int height, int fps); [DllImport("Camera")] private static extern void DestroyCamera(IntPtr obj); [DllImport("Camera")] private static extern bool GetImage(IntPtr obj, ref IntPtr data, ref int size); private int width_ = 640; private int height_ = 480; private int fps_ = 30; private IntPtr Camera_ = IntPtr.Zero; private IntPtr data_ = IntPtr.Zero; private int size_ = 0; private byte[] buffer_ = null; private RawImage background_ = null; private Texture2D tex_ = null; // Start is called before the first frame update void Start() { background_ = GameObject.FindWithTag("BackgroundImage").GetComponent<RawImage>(); Camera_ = CreateCamera(width_, height_, fps_); } void OnDestroy() { if (Camera_ != IntPtr.Zero) { DestroyCamera(Camera_); Camera_ = IntPtr.Zero; } } // Update is called once per frame void Update() { if (Camera_ == IntPtr.Zero) return; bool flag = GetImage(Camera_, ref data_, ref size_); if (!flag || size_ <= 0) return; if (buffer_ == null) { buffer_ = new byte[size_]; } if (tex_ == null) { tex_ = new Texture2D(width_, height_, TextureFormat.RGB24, false, false); } System.Runtime.InteropServices.Marshal.Copy(data_, buffer_, 0, size_); tex_.LoadRawTextureData(buffer_); tex_.Apply(); background_.texture = tex_; // byte[] bytes = tex_.EncodeToPNG(); // File.WriteAllBytes("Image.png", bytes); } }