PictureBox.Handle IntPtr转换为图像或位图

3

我需要关于海康威视IP摄像头视频流的帮助。我已经搜索了两个星期,但没有找到解决方法。

我的问题是IP摄像头动态链接库使用PictureBox.Handle将图像传输到图片框中,这个过程运行得非常好:

[DllImport("HCNetSDK.dll")]
public static extern int NET_DVR_RealPlay_V30(int lUserID, ref NET_DVR_CLIENTINFO lpClientInfo, RealDataCallBack_V30 fRealDataCallBack_V30, IntPtr pUser, bool bBlocked);

    this.realDataCallBack = new RealDataCallBack_V30(RealDataCallback);
    this.clientInfo.hPlayWnd = PictureBox.Handle;
    this.clientInfo.lChannel = channel;
    this.clientInfo.lLinkMode = 0;

    this.playHandle = NET_DVR_RealPlay_V30(this.userID, ref this.clientInfo, realDataCallBack, IntPtr.Zero, true);

我的问题是我需要处理图像,但我找不到任何方法将图像捕获为位图或图像,然后按照我想要的方式显示它。
我尝试过Bitmap.FromHbitmap(PictureBox.Handle),尝试了一些MemoryMarshel解决方案,但都没有成功。
现在我的唯一方法是从回调函数中获取数据,但这样的质量较低,帧数也较低...

与论坛网站不同,我们在 [so] 上不使用“谢谢”或“感激任何帮助”,也不使用签名。请参见“Should 'Hi', 'thanks,' taglines, and salutations be removed from posts?”。顺便说一句,“Thanks in advance”应该是“Thanks in advance”,而不是“Thanks in advanced”。 - John Saunders
好的,已经注意到了,感谢您更新我的问题。 - Jean
@Jean,我遇到了同样的问题。你有什么建议可以让我从PictureBox.Handle获取图像吗? - crispy
Jeen,我也遇到了同样的问题,你能提供一些帮助吗?我想从海康威视4通道DVR摄像头中获取图像。 - ashish bhatt
嗨,Ashish,你可以使用开源软件onvifdm。你可以阅读代码并将其集成到你的应用程序中,或者你可以更低级别地获取RTSP客户端流,使用Live555。 - Jean
使用GigE相机能否解决同样的问题?有找到什么解决方案吗? - Peter
2个回答

0

您需要将hPlayWnd设置为零。将回调函数设置为在解码数据上工作。我正在尝试理解海康威视SDK,有一些困难......

lpPreviewInfo.hPlayWnd = IntPtr.Zero;//预览窗口 live view window
m_ptrRealHandle = RealPlayWnd.Handle;
RealData = new CHCNetSDK.REALDATACALLBACK(RealDataCallBack);//预览实时流回调函数 real-time stream callback function 
m_lRealHandle = CHCNetSDK.NET_DVR_RealPlay_V40(m_lUserID, ref lpPreviewInfo, RealData, pUser);

public void RealDataCallBack(Int32 lRealHandle, UInt32 dwDataType, IntPtr pBuffer, UInt32 dwBufSize, IntPtr pUser)



//解码回调函数
        private void DecCallbackFUN(int nPort, IntPtr pBuf, int nSize, ref PlayCtrl.FRAME_INFO pFrameInfo, int nReserved1, int nReserved2)
        {
            // 将pBuf解码后视频输入写入文件中(解码后YUV数据量极大,尤其是高清码流,不建议在回调函数中处理)
            if (pFrameInfo.nType == 3) //#define T_YV12 3
            {
            //    FileStream fs = null;
            //    BinaryWriter bw = null;
            //    try
            //    {
            //        fs = new FileStream("DecodedVideo.yuv", FileMode.Append);
            //        bw = new BinaryWriter(fs);
            //        byte[] byteBuf = new byte[nSize];
            //        Marshal.Copy(pBuf, byteBuf, 0, nSize);
            //        bw.Write(byteBuf);
            //        bw.Flush();
            //    }
            //    catch (System.Exception ex)
            //    {
            //        MessageBox.Show(ex.ToString());
            //    }
            //    finally
            //    {
            //        bw.Close();
            //        fs.Close();
            //    }
            }
        }

请查看源代码


0
这段代码从句柄中提取数据并将其绘制到位图中,然后设置picturebox的图像。在旧系统上可能不需要CopyFromScreen行。
PictureBox.Image = CaptureControl(PictureBox.Handle, PictureBox.Width, PictureBox.Height);
// PictureBox.Image now contains the data that was drawn to it

    [DllImport("gdi32.dll")]
    private static extern bool BitBlt(IntPtr hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, IntPtr hdcSrc, int nXSrc, int nYSrc, int dwRop);
    public Bitmap CaptureControl(IntPtr handle, int width, int height)
    {
      Bitmap controlBmp;
      using (Graphics g1 = Graphics.FromHwnd(handle))
      {
        controlBmp = new Bitmap(width, height, g1);
        using (Graphics g2 = Graphics.FromImage(controlBmp))
        {
         g2.CopyFromScreen(this.Location.X + PictureBox.Left, this.Location.Y + PictureBox.Top, 0, 0, PictureBox.Size);

          IntPtr dc1 = g1.GetHdc();
          IntPtr dc2 = g2.GetHdc();

          BitBlt(dc2, 0, 0, width, height, handle, 0, 0, 13369376);
          g1.ReleaseHdc(dc1);
          g2.ReleaseHdc(dc2);
        }
      }

      return controlBmp;
    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接