关于8位图像buffer显示到picturebox上

最终版本:

  void showbuffer2pictmod4(byte[] buffer, int ww, int hh, PictureBox destImg)
        {
            int mod = ww % 4;//解决四位对齐问题20150716
            int temproiw = ww + (4 - mod) % 4;//其实这都是和显示相关,处理图像其实不必考虑,
            //顯示
            byte[] cutvalues = new byte[temproiw * hh * 3];
            int bytes = temproiw * hh * 3;
            Bitmap cutPic24 = new Bitmap(temproiw, hh, System.Drawing.Imaging.PixelFormat.Format24bppRgb);
            BitmapData _cutPic = cutPic24.LockBits(new Rectangle(0, 0, temproiw, hh), ImageLockMode.ReadWrite,
                                                     cutPic24.PixelFormat);

            IntPtr ptr = _cutPic.Scan0;//得到首地址

            for (int i = 0; i < hh; i++)
            {
                for (int j = 0; j < ww; j++)
                {
                    int n = i * ww + j;
                    //int m = 3 * n;
                    int m = 3 * (i * temproiw + j);
                    cutvalues[m] = buffer[n];
                    cutvalues[m + 1] = buffer[n];
                    cutvalues[m + 2] = buffer[n];

                }
            }
            System.Runtime.InteropServices.Marshal.Copy(cutvalues, 0, ptr, bytes);
            cutPic24.UnlockBits(_cutPic);
            destImg.Image = cutPic24;
        }

最初版本:

  void showbuffer2pict(byte[] buffer, int ww, int hh, PictureBox destImg)
        {
        
            byte[] cutvalues = new byte[ww * hh * 3];
            int bytes = ww * hh * 3;
            Bitmap cutPic24 = new Bitmap(ww, hh, System.Drawing.Imaging.PixelFormat.Format24bppRgb);
            BitmapData _cutPic = cutPic24.LockBits(new Rectangle(0, 0, ww, hh), ImageLockMode.ReadWrite,
                                                 cutPic24.PixelFormat);

            IntPtr ptr = _cutPic.Scan0;//得到首地址

            for (int i = 0; i < hh; i++)
            {
                for (int j = 0; j < ww; j++)
                {
                    int n = i * ww + j;
                    int m = 3 * n;
                    cutvalues[m] = buffer[n];
                    cutvalues[m + 1] = buffer[n];
                    cutvalues[m + 2] = buffer[n];

                }
            }
            System.Runtime.InteropServices.Marshal.Copy(cutvalues, 0, ptr, bytes);
            cutPic24.UnlockBits(_cutPic);
            destImg.Image = cutPic24;
        }

一直用第一版本,好几年了,中间改成24位buffer显示到picturebox,24位可以在picturebox中显示,也改成32位显示过,没什么问题,一直也很小心width4位整除问题,所以也没写进去。

直到写最终版本,原因是,我从这个8位buffer中截取的roi图像是正常的,显示也正常,而这个8位buffer显示不正常,我知道肯定函数出问题了(相机是1626*1224),改了4位对齐,下面循环中没改,还是不正常,都是细节问题,一不小心,就挂了,搞得我还用了几天海康的类似函数:

  IntPtr   m_hDisplayHandle = pictureBoxrgb.Handle;//见好就收202310171220
                        device.MV_CC_Display_NET(m_hDisplayHandle);

最后发现海康这个是回调函数显示,overlap的,pictureboxrgb.image==null.上当了,不是我想要的,因为我要用这个pictureboxrgb.image。

没办法,for循环的问题才找到。就这句话:   int m = 3 * (i * temproiw + j);

其实我想说的是,任何事情都不可能一步走到位,但最终能走到位,虽然有时相隔好几年。

以前用c++,固定思维,喜欢用sendmessage,WM_COPYDATA,这次在c#中吃了大亏(接受的动态库窗口没有title name,导致WM_COPYDATA带过来的图像去错了地方,串台了),但改过了,就算成功。感觉还是写成public调用函数,靠谱的多。

你可能感兴趣的:(机器视觉自我实现(三),机器视觉)