简体   繁体   English

C++ Memory 复制等效于 C#

[英]C++ Memory Copy Equivalent in C#

I am writing a Winform Application to capture Images from a Camera.我正在编写一个 Winform 应用程序来从相机捕获图像。 The captured raw data from the camera needs to be converted to DNG format.从相机捕获的原始数据需要转换为 DNG 格式。 The manufacturer has provided a C++ example depicting the same.制造商提供了描述相同的 C++ 示例。

I used the same logic in C#, however DNG image generated by C# code is not proper.我在 C# 中使用了相同的逻辑,但是 C# 代码生成的 DNG 图像不正确。

I think in C# code, the "memcpy_s" equivalent is not done correctly and thus it fails.我认为在 C# 代码中,“memcpy_s”等效项没有正确完成,因此它失败了。

Since i am not very thorough with C++, i might have messed up the logic in C#.由于我对 C++ 不是很彻底,我可能搞砸了 C# 中的逻辑。

Any pointers / suggestions / valuable guidance will be very helpful.任何指示/建议/有价值的指导都会非常有帮助。 Thanks a ton for your time to go through this code.非常感谢您花时间通过此代码访问 go。

C++ Code is given below. C++ 代码如下。

HRESULT hr = Nncam_PullStillImageV2(m_hcam, NULL, 24, &info);
if (SUCCEEDED(hr))
{
    void* pRawData = malloc(info.width * info.height);   // allocating memory based on width and Height of the image.
    hr = Nncam_PullStillImage(m_hcam, pRawData, 24, NULL, NULL);
    if (SUCCEEDED(hr))
    {
        unsigned nFourCC = 0, bitsperpixel = 0;
        Nncam_get_RawFormat(m_hcam, &nFourCC, &bitsperpixel);

        BITMAPINFOHEADER bmpHeader = { 0 };
        bmpHeader.biSize = sizeof(BITMAPINFOHEADER);
        bmpHeader.biPlanes = 1;
        bmpHeader.biBitCount = bitsperpixel;
        bmpHeader.biWidth = info.width;
        bmpHeader.biHeight = info.height;
        if (bitsperpixel > 8)
        {
            bmpHeader.biSizeImage = info.width * info.height * 2;
        }
        else
        {
            bmpHeader.biSizeImage = info.width * info.height;
        }
        bmpHeader.biCompression = nFourCC;

        // core logic for DNG conversion adding headers and rawimage data to Ptr
        void* pDIB = malloc(sizeof(BITMAPINFOHEADER) + bmpHeader.biSizeImage);
        memcpy_s(pDIB, sizeof(BITMAPINFOHEADER), &bmpHeader, sizeof(BITMAPINFOHEADER));
        memcpy_s((char*)pDIB + sizeof(BITMAPINFOHEADER), bmpHeader.biSizeImage,
            pRawData, bmpHeader.biSizeImage);
        XIMAGEINFO imageInfo = { 0 };
        imageInfo.iType = IMAGEFORMAT_DNG;
        imageInfo.iCodec = 1;
        BOOL res = ImageLib_Save(_T("image.dng"), pDIB, &imageInfo);
        free(pDIB);
    }
    free(pRawData);
}

C# Code C#代码

 if (cam_.PullStillImageV2(IntPtr.Zero, 24, out info))   /* peek the width and height */
            {
                uint pnWidth, pnHeight;
                var sbmp = new Bitmap((int)info.width, (int)info.height, PixelFormat.Format24bppRgb);
                var bmpdata = sbmp.LockBits(new Rectangle(0, 0, sbmp.Width, sbmp.Height), ImageLockMode.WriteOnly, sbmp.PixelFormat);
                if (cam_.PullStillImage(bmpdata.Scan0, 24, out pnWidth, out pnHeight))
                {
                    uint nFourCC = 0, bitsperpixel = 0;
                    cam_.get_RawFormat(out nFourCC, out bitsperpixel);
                    BITMAPINFOHEADER bmpHeader = new BITMAPINFOHEADER();
                    bmpHeader.Init();
                    bmpHeader.biPlanes = 1;
                    bmpHeader.biBitCount = bitsperpixel;
                    bmpHeader.biWidth = info.width;
                    bmpHeader.biHeight = info.height;
                    if (bitsperpixel > 8)
                    {
                        bmpHeader.biSizeImage = info.width * info.height * 2;
                    }
                    else
                    {
                        bmpHeader.biSizeImage = info.width * info.height;
                    }
                    bmpHeader.biCompression = nFourCC;

        // adding header and rawdata to PDIB might not be correct way as shown in C++
                    IntPtr pDIB = Marshal.AllocHGlobal((int)(Marshal.SizeOf(typeof(BITMAPINFOHEADER)) + bmpHeader.biSizeImage));
                    Marshal.StructureToPtr(bmpHeader, pDIB, true);
                    CopyMemory(pDIB + Marshal.SizeOf(typeof(BITMAPINFOHEADER)), bmpdata.Scan0, bmpHeader.biSizeImage);


                    XIMAGEINFO imageInfo = new XIMAGEINFO();
                    imageInfo.iType = 17;
                    imageInfo.iCodec = 1;
                    ImageLib_Save("image.dng", pDIB, ref imageInfo);
                }
            }

Being more comfortable with C++ than C#, my impression is that the stuff done in C++ to add a header is simply to be able to identify the malloc'ed memory as an image after saving it. Being more comfortable with C++ than C#, my impression is that the stuff done in C++ to add a header is simply to be able to identify the malloc'ed memory as an image after saving it.

I would expect the C# Bitmap class to handle that for you.我希望 C# Bitmap class 能够为您处理。

Have you tried simply saving the Bitmap?您是否尝试过简单地保存 Bitmap?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM