C#從三通道影象資料流轉到HObject
用相機SDK採圖的話很多時候得到的是一個數據流(byte[])或者指標IntPtr,單通道轉換gen_image1還比較方便,
如果是三通道的話有兩種方法
一、可用gen_image3這個函式這裡會要處理三個顏色分量的指標,是個比較簡單呆板的轉換方法;
下面進入正題。
//名稱空間
using System;
using System.Drawing;
using System.IO;
using System.Threading;
using System.Windows.Forms;
using HalconDotNet;
using System.Drawing.Imaging;
…………………………………………………………………………………………………………………………
//這裡的Image.Buffer是byte[],由於裡面還包含了相機型號等其它資訊,不能直接拿來操作
MemoryStream buffer = new MemoryStream(Image.Buffer);
Bitmap bmp = new Bitmap(buffer);//用BitMap做中轉
this.pictureBox1.Image = bmp;
//做好準備
HOperatorSet.SetPart(this.hWindowControl1.HalconWindow, 0, 0, bmp.Height, bmp.Width);
HObject halcon_image;
BitmapData bmp_data = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadOnly, bmp.PixelFormat);//鎖定BitMap
byte[] arrayR = new byte[bmp_data.Width * bmp_data.Height];//紅色陣列
byte[] arrayG = new byte[bmp_data.Width * bmp_data.Height];//綠色陣列
byte[] arrayB = new byte[bmp_data.Width * bmp_data.Height];//藍色陣列
byte* pBmp = (byte*)bmp_data.Scan0;//BitMap的頭指標
//下面的迴圈分別提取出紅綠藍三色放入三個陣列
for (int R = 0; R < bmp_data.Height; R++)
{
for (int C = 0; C < bmp_data.Width; C++)
{
//因為記憶體BitMap的儲存方式,行寬用Stride算,C*3是因為這是三通道,另外BitMap是按BGR儲存的
byte* pBase = pBmp + bmp_data.Stride * R + C * 3;
arrayR[R * bmp_data.Width + C] = *(pBase + 2);
arrayG[R * bmp_data.Width + C] = *(pBase + 1);
arrayB[R * bmp_data.Width + C] = *(pBase);
}
}
//得到三個陣列的頭指標,C#特色
fixed (byte* pR = arrayR, pG = arrayG, pB = arrayB)
{
HOperatorSet.GenImage3(out halcon_image, "byte", bmp_data.Width, bmp_data.Height,
new IntPtr(pR), new IntPtr(pG), new IntPtr(pB));
//如果這裡報錯,仔細看看前面有沒有寫錯
}
bmp.UnlockBits(bmp_data);//用完了一定要解除鎖定
//顯示OK,跟PictureBox顯示的圖片一模一樣,哦耶!
HOperatorSet.DispObj(halcon_image, this.hWindowControl1.HalconWindow);
HOperatorSet.WriteImage(halcon_image, "bmp", 0, "Halcon_Image.bmp");//這個bmp檔案很大
//佔用記憶體很多,建議手動清理一下
二、可用GenImageInterleaved函式,具體方法見例項,這裡暫時不舉例;