1.******************************
C#调用vc++ dll 传递参数的问题(Bitmap 转换为 opencv mat ),保存后图片不一样。
vc++ 代码
bool Recognize(Point_2F *arr,uchar* b) { Mat src=cv::Mat(415,770,CV_8UC3,b); /*for (int i=0;i<src.rows;i++) { memcpy(src.ptr(i),b+i*src.cols,src.cols); }*/ cv::imwrite("D:\\my_2_testfiles\\111_before.png",src); // 保存的照片和原来的照片不一样而且大小也不一样? }
C#代码
[DllImport("rectanglepoints.dll", EntryPoint = "Recognize", CallingConvention = CallingConvention.Cdecl)] static extern byte Recognize(IntPtr arr, IntPtr b);
{ // Create a new bitmap. Bitmap bmp = new Bitmap("D:\\my_2_testfiles\\111.png"); // Lock the bitmap's bits. Rectangle rect = new Rectangle(0, 0, bmp.Width, bmp.Height); System.Drawing.Imaging.BitmapData bmpData = bmp.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite, bmp.PixelFormat); // Get the address of the first line. IntPtr ptrImg = bmpData.Scan0; bool ret; ret = Convert.ToBoolean(Recognize(IntPtr.Zero, ptrImg)); // Unlock the bits. bmp.UnlockBits(bmpData); Console.Read(); }
照片附加
原图:
调用vc++ dll后保存的图片
2.******************************************************************
C#Bitmap和C++ opencv Mat相互转换 C#调用C++编译成的dll,这个dll中包含Opencv个的Mat到c#的Bitmap转换,具体代码如下: C++部分: 首先创建win32应用程序,选择类库模板 DLL_APIuchar * _stdcall run1(char* filename, int&width, int&height, int&step) { IplImage* uu = cvLoadImage(filename); IplImage * dst1 = cvCreateImage(cvSize(uu->width, uu->height), 8, 1); cvCvtColor(uu, dst1, CV_RGB2GRAY); Matss = cvarrToMat(uu); uchar * data = new uchar[uu->width*uu->height * 3]; data = ss.data; width = ss.size().width; height = ss.size().height; step = ss.step; return data; } C#中调用这个dll [DllImport(@"E:\Files\BarcodeProject\Code\testCode\OpenCvAssemblies\Debug\OpenCvAssemblies.dll" )] publicstaticexternIntPtr run1(string a, outint width, outint height, outint step); 至此完成C++ Mat到Bitmap的转换 下面是Bitmap 到 Mat的转换 C# 部分 publicstaticBitmapInfoGetImagePixel(Bitmap Source) { byte[] result; int step; intiWidth = Source.Width; intiHeight = Source.Height; Rectanglerect = newRectangle(0, 0, iWidth, iHeight); System.Drawing.Imaging.BitmapDatabmpData = Source.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite, Source.PixelFormat); IntPtriPtr = bmpData.Scan0; intiBytes = iWidth * iHeight * 3; //根据通道数进行设置 byte[] PixelValues = newbyte[iBytes]; //int time = Environment.TickCount; System.Runtime.InteropServices.Marshal .Copy(iPtr, PixelValues, 0, iBytes); //time = Environment.TickCount - time; //Console.WriteLine(time.ToString() + "ms"); Source.UnlockBits(bmpData); step = bmpData.Stride; result = PixelValues; // return result; // step = 0; BitmapInfo bi = newBitmapInfo{ Result=result, Step=step }; return bi; } } ///<summary> /// Bitmap信息类 ///</summary> publicclassBitmapInfo { publicbyte[] Result { get; set; } publicint Step { get; set; } } Step 是扫描的步长,这个很重要,如果这个步长不是原来的值,就会造成图像偏移,从而造成失真。 C++部分 DLL_APIvoid_stdcallshow(uchar* data,intwidth,intheight,intstep) { Matimage(height,width, CV_8UC3,data,step); //image.data = data; imshow("Image",image); //Mat(int rows, int cols, int type, void* data, size_t step = AUTO_STEP); } C# 中调用方式 BitmapInfo bi = GetImagePixel(bitmap); show(bi.Result,bitmap.Width,bitmap.Height,bi.Step); 至此完成他们的相互转换