书接上文Emgucv不完整图像分割试验(三),将图切割N个小块后如何在Imagebox内选中所需要的小块的问题就浮上来了,
本来是一个很简单的问题,但如果加上滑动条和缩放后,整个事情就变得变态起来了。。。
涉及的数值太多,画了上面个图辅助说明。
A:现在图的尺寸(假定有放大缩小)
B:ImageBox的尺寸(假定随窗口一起变化)
C:鼠标相对ImageBox的坐标(这个也就是我们直接获取的数据,然后用它推导最后的落点)
D\E:水平和垂直滑动条的高度和宽度(这个很变态的,出现的时候,之前的B的数值也会被修改,切切记住)
F\G:水平和垂直滑动条当前的数值
H\I:水平和垂直滑动条的最大值(不是直接取到的那个数值,而是真实滑到最后的值,两者很大可能是不等的)
J:图片的缩放比
目标:将C的坐标换算到真实的(没缩放)的图片的坐标。步骤如下:
1:A-B,获取假如图片拉到底,超出的宽和高(用于后面计算滑动条的步长)
2:判断是否有滑动条,如果有,就修正,分别减去D,E的数值,因为有了滑动条则ImageBox的显示区也就变化了。
3:修正H,I的数值(原先的MAX是Imagebox生成滑动条时自动生成的,但划到底一般不是原先的最大值,2和3两步卡了我整整一天。也是本贴的主要内容)
4:将1的值/3的值,算出一个滑动条数值+1相对移动的距离
5:用F,G和4算出的值+C的值算出当前当前点在缩放图的坐标。
6:用5的值和J的值算出最后C点在真实图坐标。(注意浮点数和整数的换算和向上取整)
代码修修补补弄出来,很乱,需要的同学最好自己重写下,或者有高手有更好的版本麻烦发我一份:
//校准滑动条
if (this.checkBox3.Checked)
{
this.textBox7.Text = this.imageBox1.HorizontalScrollBar.Value.ToString();
this.textBox8.Text = this.imageBox1.VerticalScrollBar.Value.ToString();
}
//修正鼠标坐标为图片坐标
if (this.checkBox2.Checked)
{
int originslWidth = this.imageBox1.Width;
int originslHeight = this.imageBox1.Height;
if (this.imageBox1.VerticalScrollBar.Width > 0)
{
originslWidth = this.imageBox1.Width- this.imageBox1.VerticalScrollBar.Width;
}
if (this.imageBox1.HorizontalScrollBar.Height > 0)
{
originslHeight = this.imageBox1.Height- this.imageBox1.HorizontalScrollBar.Height;
}
double currentWidth = this.imageBox1.Image.Bitmap.Width * this.imageBox1.ZoomScale;
double currentHeight = this.imageBox1.Image.Bitmap.Height * this.imageBox1.ZoomScale;
double black_left = 0;
double black_top = 0;
if (currentWidth > originslWidth)
{
black_left = currentWidth - originslWidth;
}
if (currentHeight > originslHeight)
{
black_top= currentHeight - originslHeight;
}
double currentblack_leftstep = 0;
double currentblack_topstep = 0;
int maxH = 100;
int maxV = 100;
if (this.textBox7.Text != "")
{
maxH = Convert.ToInt32(this.textBox7.Text); }
if (this.textBox8.Text != "")
{
maxV = Convert.ToInt32(this.textBox8.Text); }
if (this.imageBox1.HorizontalScrollBar.Maximum > 0)
{
currentblack_leftstep = black_left / maxH;
}
if (this.imageBox1.VerticalScrollBar.Maximum > 0)
{
currentblack_topstep = black_top / maxV;
}
double currentX = e.X;
double currentY = e.Y;
if(this.imageBox1.HorizontalScrollBar.Value>1)
currentX = currentblack_leftstep*(this.imageBox1.HorizontalScrollBar.Value) + e.X;
if (this.imageBox1.VerticalScrollBar.Value > 1)
currentY = currentblack_topstep*(this.imageBox1.VerticalScrollBar.Value) + e.Y;
int xx =Convert.ToInt32( Math.Ceiling(Convert.ToSingle(currentX / this.imageBox1.ZoomScale)));
int yy = Convert.ToInt32(Math.Ceiling(Convert.ToSingle(currentY / this.imageBox1.ZoomScale)));
PointF tempP = new PointF(xx, yy); //后面我还做了其它,这里就不贴出了}
最后放个结果图,右下两个坐标,一个是鼠标单击的坐标,一个是最后换算的坐标(我的图尺寸为103*130,我点的是最右下)
初开博客,目的是交流与合作,本人QQ:273651820。