Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/320.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/148.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 从C++; 项目中,我使用UNIGIS3D的C脚本和C++通过DLIMPOUNT。我的目标是游戏场景有2个立方体(立方体和CuBe2)< /> >这一个立方体纹理通过我的笔记本电脑和Unity的 WebCAMPrime.Pror()/Cudio显示了现场视频,另一个立方体纹理显示了外部C++函数 PrimeSimeAGE()/处理过的视频。_C#_C++_Unity3d_Pinvoke - Fatal编程技术网

C# 从C++; 项目中,我使用UNIGIS3D的C脚本和C++通过DLIMPOUNT。我的目标是游戏场景有2个立方体(立方体和CuBe2)< /> >这一个立方体纹理通过我的笔记本电脑和Unity的 WebCAMPrime.Pror()/Cudio显示了现场视频,另一个立方体纹理显示了外部C++函数 PrimeSimeAGE()/处理过的视频。

C# 从C++; 项目中,我使用UNIGIS3D的C脚本和C++通过DLIMPOUNT。我的目标是游戏场景有2个立方体(立方体和CuBe2)< /> >这一个立方体纹理通过我的笔记本电脑和Unity的 WebCAMPrime.Pror()/Cudio显示了现场视频,另一个立方体纹理显示了外部C++函数 PrimeSimeAGE()/处理过的视频。,c#,c++,unity3d,pinvoke,C#,C++,Unity3d,Pinvoke,代码上下文: extern "C" { void ProcessImage(unsigned char* raw, int width, int height); } ... void ProcessImage(unsigned char* raw, int width, int height) { for(int y=0; y < height; y++) { for(int x=0; x < width; x++) {

代码上下文:

extern "C"
{
    void ProcessImage(unsigned char* raw, int width, int height);
}
...

void ProcessImage(unsigned char* raw, int width, int height)
{
    for(int y=0; y < height; y++)
    {
        for(int x=0; x < width; x++)
        {
            unsigned char* pixel = raw + (y * width * 4 + x * 4);
            pixel[0] = pixel[0]-(unsigned char)2; //R
            pixel[1] = pixel[1]-(unsigned char)2; //G
            pixel[2] = pixel[2]-(unsigned char)2; //B
            pixel[3] = pixel[3]-(unsigned char)2; //Alpha
        }
    }
}
[DllImport("test22")]
private static extern void ProcessImage(IntPtr texData, int width, int height);

unsafe void ProcessImage(Texture2D texData)
{
    Color32[] texDataColor = texData.GetPixels32();
    System.Array.Reverse(texDataColor);

    //Pin Memory
    fixed (Color32* p = texDataColor)
    {
        ProcessImage((IntPtr)p, texData.width, texData.height);
    }
    //Update the Texture2D with array updated in C++
    texData.SetPixels32(texDataColor);
    texData.Apply();
}
在C++中,我定义了

struct Color32
{
    unsigned char r;
    unsigned char g;
    unsigned char b;
    unsigned char a;
};
功能是

extern "C"
{
    Color32* ProcessImage(Color32* raw, int width, int height);
}
...

Color32* ProcessImage(Color32* raw, int width, int height)
{
    for(int i=0; i<width*height ;i++)
    {
       raw[i].r = raw[i].r-2;
       raw[i].g = raw[i].g-2;
       raw[i].b = raw[i].b-2;
       raw[i].a = raw[i].a-2;
    }
    return raw;
}
获取相机位置并设置立方体1、立方体2纹理

void Start()
{
    WebCamDevice[] wcd = WebCamTexture.devices;

    if(wcd.Length==0)
    {
        print("Cannot find a camera");
        Application.Quit();
    }
    else
    {
        webCamTexture = new WebCamTexture(wcd[0].name);
        cube.GetComponent<Renderer>().material.mainTexture = webCamTexture;

        tx2D = new Texture2D(webCamTexture.width, webCamTexture.height);
        cube2.GetComponent<Renderer>().material.mainTexture = tx2D;

        webCamTexture.Play();
    }
}
结果:

extern "C"
{
    void ProcessImage(unsigned char* raw, int width, int height);
}
...

void ProcessImage(unsigned char* raw, int width, int height)
{
    for(int y=0; y < height; y++)
    {
        for(int x=0; x < width; x++)
        {
            unsigned char* pixel = raw + (y * width * 4 + x * 4);
            pixel[0] = pixel[0]-(unsigned char)2; //R
            pixel[1] = pixel[1]-(unsigned char)2; //G
            pixel[2] = pixel[2]-(unsigned char)2; //B
            pixel[3] = pixel[3]-(unsigned char)2; //Alpha
        }
    }
}
[DllImport("test22")]
private static extern void ProcessImage(IntPtr texData, int width, int height);

unsafe void ProcessImage(Texture2D texData)
{
    Color32[] texDataColor = texData.GetPixels32();
    System.Array.Reverse(texDataColor);

    //Pin Memory
    fixed (Color32* p = texDataColor)
    {
        ProcessImage((IntPtr)p, texData.width, texData.height);
    }
    //Update the Texture2D with array updated in C++
    texData.SetPixels32(texDataColor);
    texData.Apply();
}

结果是立方体1的纹理仅显示实时视频,而无法使用立方体2的纹理显示处理后的数据

错误:

使用数组中无效的像素数调用SetPixels32 UnityEngine.Texture2D:SetPixels32(Color32[])网络摄像头:更新()(位于 资产/脚本/网络摄像头。cs:45)

我不明白为什么当我将数组a输入到SetPixels32时,数组中的像素数无效

有什么想法吗


更新(2018年10月10日)


多亏了@Programmer,现在它可以通过pin内存工作了

顺便说一句,我发现了一些关于Unity引擎的小东西。当Unity摄像头在0到1秒之间运行时,
webCamTexture.width
webCamTexture.height
始终返回
16x16
大小,即使请求更大的图像,例如1280x720,它也会在1秒后返回正确的大小。因此,我引用此函数并延迟2秒运行
Update()
函数中的
Process()
,并在
Process()
函数中重置纹理2D大小。它可以很好地工作:

delaytime = 0;
void Update()
{
    delaytime = delaytime + Time.deltaTime;
    Debug.Log(webCamTexture.width);
    Debug.Log(webCamTexture.height);

    if (delaytime >= 2f)
        Process();
}
unsafe void Process()
{
    ...

    if ((Test.width != webCamTexture.width) || Test.height != webCamTexture.height)
    {
       Test = new Texture2D(webCamTexture.width, webCamTexture.height, TextureFormat.ARGB32, false, false);
       cube2.GetComponent<Renderer>().material.mainTexture = Test;
       Debug.Log("Fixed Texture dimension");
    }
    ...
}
delaytime=0;
无效更新()
{
delaytime=delaytime+Time.deltaTime;
Log(webCamTexture.width);
Log(webCamTexture.height);
如果(延迟时间>=2f)
过程();
}
不安全的无效进程()
{
...
if((Test.width!=webCamTexture.width)| | Test.height!=webCamTexture.height)
{
测试=新纹理2D(webCamTexture.width、webCamTexture.height、TextureFormat.ARGB32、false、false);
cube2.GetComponent().material.mainTexture=测试;
Log(“固定纹理维度”);
}
...
}

c不返回理解C++中的<代码> COLL32 对象。如果将返回类型设置为
unsigned char*
,然后在C端使用
marshall.Copy
将返回的数据复制到字节数组中,然后使用将数组加载到
Texture2D
中,则此方法会起作用。是一个从C#返回字节数组的示例


我不建议您返回数据,因为这很昂贵。填充传递给函数的数组,然后将该数组重新分配给
纹理2D

C++:

extern "C"
{
    void ProcessImage(unsigned char* raw, int width, int height);
}
...

void ProcessImage(unsigned char* raw, int width, int height)
{
    for(int y=0; y < height; y++)
    {
        for(int x=0; x < width; x++)
        {
            unsigned char* pixel = raw + (y * width * 4 + x * 4);
            pixel[0] = pixel[0]-(unsigned char)2; //R
            pixel[1] = pixel[1]-(unsigned char)2; //G
            pixel[2] = pixel[2]-(unsigned char)2; //B
            pixel[3] = pixel[3]-(unsigned char)2; //Alpha
        }
    }
}
[DllImport("test22")]
private static extern void ProcessImage(IntPtr texData, int width, int height);

unsafe void ProcessImage(Texture2D texData)
{
    Color32[] texDataColor = texData.GetPixels32();
    System.Array.Reverse(texDataColor);

    //Pin Memory
    fixed (Color32* p = texDataColor)
    {
        ProcessImage((IntPtr)p, texData.width, texData.height);
    }
    //Update the Texture2D with array updated in C++
    texData.SetPixels32(texDataColor);
    texData.Apply();
}
使用:

public Texture2D tex;

void Update()
{
    ProcessImage(tex);
}

如果不想使用<代码>不安全的< /代码>和<代码>固定< /COD>关键字,也可以使用<代码> GCHANDLE。ALC/C >代码之前,将其发送到C++端,并使用“代码> GCHANDLE”。如何做到这一点,请参阅帖子


如果您遇到以下异常:

使用数组中无效的像素数调用SetPixels32 UnityEngine.Texture2D:SetPixels32(Color32[])网络摄像头:更新()(位于 资产/脚本/网络摄像头。cs:45)

这意味着您正在调用的
SetPixels32
上的
Texture2D
WebCamTexture
纹理具有不同的大小或纹理维度。要解决此问题,请在调用
SetPixels32
之前,检查纹理维度是否已更改,然后调整目标纹理的大小以与
WebCamTexture
匹配

替换

tx2D.SetPixels32(rawImg);
tx2D.Apply();


您能否共享定义和初始化Texture2D tx2D变量的代码?Texture2D tx2D初始化新的Texture2D(webCamTexture.width,webCamTexture.height)
代码已上载,您可以在此网站上观看[链接:谢谢你的回复。不幸的是,我引用了你的建议,思考并修改了代码。它也出现了相同的错误消息。如果你想查看代码的详细信息,我已经上传到这个网站:对答案进行了编辑以解决该错误。请查看。如果仍然存在问题,请告诉我。别忘了访问acc如果您的问题通过单击我答案上的绿色复选标记得到解决,请接受答案。感谢@Programmer,现在它可以通过pin内存工作。但是,我有一个小问题,如果我使用OpenCV库处理图像。有关详细信息,请参阅我的“更新”帖子对不起,这不是它在这里的工作原理。这个帖子不是关于OpenCV和关于从C++更新Trutu2D像素的原始帖子。我想问题现在已经解决了。当你问一个问题,它被解决了,但是你想做不同的事情,并遇到问题,你接受当前的答案,然后创建新的问题。你应该Cre。在OpenCV帖子中添加新问题。请确保在新问题中也标记OpenCV。您可能希望删除对此问题所做的OpenCV编辑。