首先,我瞄上了微软的toolbox,就是小画家(mspaint)里边的工具箱,在vc++时代,错过了,没实现他,当你发现他重要时,已经到了c#时代,没关系,任何时候都不晚,做一个模拟吧,ok,我买过一本连连看游戏c#实现,照抄写了一遍,调试成功,丢给儿子玩,顺便显摆一下(嘻嘻!),然后,进入正题,其实想要的是icon位图加载到每一个矩形格子中,vc++原来有实现,这不,c#有现成的,就参考过来了,忽然之间,痴迷玩过的红色警戒界面也映入脑海,某一天,是否?我也可以写一个这样的游戏,又跑远了,再扯回来,红色警戒的武器选项不也是toolbox吗?好,加载icon有了,toolbox也有了(连连看的鼠标操作太单调),忽然间,又有一个想法,这个toolbox的分割矩形为什么不用自己的线图像矩形设计呢?是的,这是一个伟大的想法,当你知道利用自己的长处而拾阶而上时(很多人无视自己的长处,这个东西像极了习惯,你不仅没有发掘他,甚至站到了不耐烦的那一面,比如健康的人),便知道了从前自己浪费掉了多少自己的资源,你为什么又要从头而来呢?屡次失败,而不得其法。另外,你的东西,自己都不用,别人怎么会用?自己的价值靠别人去挖掘,会来的很晚,或许又遗忘,丢弃了,像极了学过的知识,还回去之后,自己也丢失了。当你学会回顾,和总结,并给自己一点小奖励,那么你就会欣赏自己,当自信找回来,不仅仅是程序,而人生也会别开生面。感叹啊!出发点何其相似,而结果差别怎么这么大呢?(其实也不大,都是玩完蛋!笑!哈哈哈......开心与不开心,追求和放弃,习惯的培养,导致的一念之差而已,计算机最喜欢放大错误,像一个显微镜,让你谬以千里,所以程序员很喜欢找错误,bug,虫子),再中断返回,当你把线图像工具变成toolbox,一试,ok,太喜欢了,抄一遍,总结一遍,进步一点,下一步 走起!(逻辑的好处是,即使你是错的,他永远在正确的错,这就是对错的距离,最怕的是,你连逻辑都没有!世上本无路,就怕你无路!对逻辑的确认,就是对真理的确认,也是对人生的确认,这才是站在巨人肩上,站在巨人肩上,也没那么容易。对错,是站在逻辑肩上,而感觉,不要谈对错。)
其次,我瞄上了微软的dll(动态链接库),谁没有一点小私心,但是现在被击破了,原因是,你认为有价值的东西,谁在乎?一厢情愿罢了,与其这样,不如奉献给想要而又未得到的人(也要花功夫),或许还有用处,或许某一天,他会念叨你一句,这不就得了吗?到当下,dll已经用进程序去,小私心带来了不少麻烦!而谁没一点小理想?让程序分而治之,但你收获的是,dll其实与私心一点关系都没有,他只是一种技术而已,像程序中的一个函数,又像作文中的自然段,他会让你的这个段凝练,独立,方便调用,缺点就是调试时监控不到,理想照进现实。我把相机取像和传递出图像打包成了一个dll,然后把toolbox和tools之间的联系(接受图像和处理图像及给出结果)打包了一个dll,而中间应用程序(你自己创建的)会调用这两个dll,起桥梁作用。
第三,先说明白一个dll(工具盒及图像处理),首先toolbox中有两个工具(剩下的回头再添加),一个是原图像(静态的,相机实时中的一幅,有需求时,传递过来的),一个是标定(由原图像传递过来),在一个picturebox中,我们鼠标双击每一个工具,就可以添加进来,在自己规划的位置,而,把原图像要传递给标定,就拉一条线在两个工具之间表达,你要查看每一个工具,就去鼠标双击它,它会呈现一个界面(form),前面标定的form界面已经有了,可以看一看,原图像form界面简单的多,显示了截取相机的一幅实时图像,并且可以用roi(感兴趣区域)工具截取感兴趣区域放大观察研究。在相机的dll中,有一个copydata传递图像的按键,点击后,只要原图像和标定间有连线,标定界面打开,图像就有了,原图像自不待言。这是模仿visionpro的,但代码是自己原创的,这叫打开神奇。其实picturebox中可以用微软提供的tree数据结构,但自己不熟悉,那么就再一次用自己的长处和熟练的,这一发不可收拾,屡试不爽,要在界面画任何点线面,都可以从线图像工具设计演变过来。
第四,我们具体而微的看一下原图像(sourceIMG)是怎么接受图像并传递图像给标定的(calibration),标定和以后的工具都使用这种统一方法。以下是原图像form的源代码,c#的:
public partial class ImageSourceForm : Form
{
//可以定义一个bitmap,和一个二维图像数组。bitmap用来显示,二维数组用来处理
public Bitmap ISbmp = null;
// public Bitmap IS_curBitmap;
public byte[] IS_orgImg = null;
public int IS_W;
public int IS_H;
public ImageSourceForm()
{
InitializeComponent();
}
private void ImageSourceForm_Load(object sender, EventArgs e)
{
}
public void init(int w,int h)
{
IS_W = w;
IS_H = h;
IS_orgImg = new byte[IS_W * IS_H];
if (IS_W == 1024)
{ pictureBox1.Size = new Size(512, 384); }
else if (IS_W == 1600)
{
pictureBox1.Size = new Size(400, 300);
}
else if (IS_W == 2448)
{
pictureBox1.Size = new Size(612, 512);
}
}
public void mgUpdate()
{
if (ISbmp != null)
{
pictureBox1.Image = ISbmp;
pictureBox1.Invalidate();
}
}
private byte[] tempImageROI;
bool m_btempImageroi = false;
Point mouseclickpoint = new Point();
private void pictureBox1_MouseClick(object sender, MouseEventArgs e)
{
if (ISbmp == null) { return; }
int H = ISbmp.Height;
int W = ISbmp.Width;
int _RoiW = 200;
int _RoiH = 200;
int _RoiX=0, _RoiY=0;
if (IS_W == 1024)
{
_RoiX = e.X * 2 - 100;//比例为2
_RoiY = e.Y * 2 - 100;
}
if (IS_W == 1600)
{
_RoiX = e.X * 4 - 100;//比例为4
_RoiY = e.Y * 4 - 100;
}
if (IS_W == 2448)
{
_RoiX = e.X * 4 - 100;//比例为4
_RoiY = e.Y * 4 - 100;
}
tempImageROI = new byte[_RoiW * _RoiH];
for (int i = 0; i < _RoiH; i++)
for (int j = 0; j < _RoiW; j++)
{
tempImageROI[i * _RoiW + j] = IS_orgImg[((i + _RoiY) * W + j + _RoiX)];
}
m_btempImageroi= true;
byte[] cutvalues = new byte[_RoiW * _RoiH * 3];
int bytes = _RoiW * _RoiH * 3;
Bitmap cutPic24 = new Bitmap(_RoiW, _RoiH, System.Drawing.Imaging.PixelFormat.Format24bppRgb);
BitmapData _cutPic = cutPic24.LockBits(new Rectangle(0, 0, _RoiW, _RoiH), ImageLockMode.ReadWrite,
cutPic24.PixelFormat);
IntPtr ptr = _cutPic.Scan0;//得到首地址
for (int i = 0; i < _RoiH; i++)//图像复原,即由8位图变成24位图像
{
for (int j = 0; j < _RoiW; j++)
{
int n = i * _RoiW + j;
int m = 3 * n;
cutvalues[m] = tempImageROI[n];
cutvalues[m + 1] = tempImageROI[n];
cutvalues[m + 2] = tempImageROI[n];
}
}
//把cutvalues数组给ptr
System.Runtime.InteropServices.Marshal.Copy(cutvalues, 0, ptr, _RoiH * _RoiW * 3);
cutPic24.UnlockBits(_cutPic);
pictureBox2.Size = new System.Drawing.Size(_RoiW, _RoiH);
pictureBox2.Image = cutPic24;
//Graphics g = pictureBox1.CreateGraphics();
//Pen p = new Pen(Color.Red);
if (IS_W == 1024)
{
// g.DrawRectangle(p, e.X - 100 / 2, e.Y - 100 / 2, 200 / 2, 200 / 2);
mouseclickpoint = new Point(e.X - 100 / 2, e.Y - 100 / 2);
}
if (IS_W == 1600)
{
//g.DrawRectangle(p, e.X - 100 / 4, e.Y - 100 / 4, 200 / 4, 200 / 4);
mouseclickpoint = new Point(e.X - 100 / 4, e.Y - 100 / 4);
}
if (IS_W == 2448)
{
//g.DrawRectangle(p, e.X - 100 / 4, e.Y - 100 / 4, 200 / 4, 200 / 4);
mouseclickpoint = new Point(e.X - 100 / 4, e.Y - 100 / 4);
}
pictureBox1.Invalidate();
}
private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
Graphics g = e.Graphics;
if (ISbmp != null)
{
if (mouseclickpoint.X != 0)
{
if (IS_W == 1024)
{
g.DrawRectangle(new Pen(Color.Red), mouseclickpoint.X, mouseclickpoint.Y, 200 / 2, 200 / 2);
}
if (IS_W == 2448)
{
g.DrawRectangle(new Pen(Color.Red), mouseclickpoint.X, mouseclickpoint.Y, 200 / 4, 200 / 4);
}
if (IS_W == 1600)
{
g.DrawRectangle(new Pen(Color.Red), mouseclickpoint.X, mouseclickpoint.Y, 200 / 4, 200 / 4);
}
}
}
}
private void pictureBox2_MouseMove(object sender, MouseEventArgs e)
{
pictureBox2.Focus();
}
private float glob_ScaleX = 1;
private float glob_ScaleY = 1;
private void pictureBox2_MouseWheel(object sender, MouseEventArgs e)
{
if (pictureBox1.Image != null)//????????????1,!!!!!!!!!2
{
if (e.Delta > 0)
{
glob_ScaleX += (float)(e.Delta / 1200.0);
glob_ScaleY += (float)(e.Delta / 1200.0);
}
else
{
glob_ScaleX -= (float)((-e.Delta) / 1200.0);
glob_ScaleY -= (float)((-e.Delta) / 1200.0);
}
pictureBox2.Invalidate();
}
}
private void pictureBox2_Paint(object sender, PaintEventArgs e)
{
int _RoiW = 200;
int _RoiH = 200;
Graphics g = e.Graphics;
pictureBox2.Size = new System.Drawing.Size((int)(_RoiW * glob_ScaleX),
(int)(_RoiH * glob_ScaleY));
g.ScaleTransform(glob_ScaleX, glob_ScaleY);
if (pictureBox2.Image != null)
g.DrawImage(pictureBox2.Image, 0, 0);
}
}
待续(慢慢来!...........)每天一点小改变☺
我的邮箱liuganggang_1978@163.com;734523623@qq.com