相关变量
public struct ImageMosaic
{
// 原图
public static string Image;
// 判断是否已经马赛克 避免重复打码
public static bool[,] IsMosaic;
public static ManualResetEvent MosaicEvent = new ManualResetEvent(false);
public static int MosaicSize;
public static bool IsEnterPbx;
public static bool IsLeave;
}
马赛克线程
public static Thread MosaicTask = new Thread(() =>
{
while (true)
{
yVariables.ImageMosaic.MosaicEvent.WaitOne();
if (yVariables.ImageMosaic.IsLeave == true)
{
yVariables.ImageMosaic.MosaicEvent.Reset();
}
OpenCvSharp.Mat mm = new OpenCvSharp.Mat();
mm = yImageConvert.ImageToMat(Form1.Instance.pbxMosaic.Image);
bool en = true;
int MX = 0, MY = 0;
Form1.Instance.Invoke(new Action(() =>
{
MX = Form1.Instance.pbxMosaic.PointToClient(Control.MousePosition).X;
MY = Form1.Instance.pbxMosaic.PointToClient(Control.MousePosition).Y;
}));
// 获取的是鼠标相对于picbox左上角的位置 需要转化成相对于图像左上角的位置
// 图片大小不一定等于picbox的大小 picbox的sizemode是StretchImage
// 鼠标位置对应成比例 在原图上处理 而不是在picbox内的图片处理
en = MX > 0 && MX < Form1.Instance.pbxMosaic.Width;
en = en && MY > 0 && MY < Form1.Instance.pbxMosaic.Height;
if (en)
{
int x = MX * mm.Width / Form1.Instance.pbxMosaic.Width;
int y = MY * mm.Height / Form1.Instance.pbxMosaic.Height;
if (yVariables.ImageMosaic.IsMosaic[y, x] == false)
{
yVariables.ImageMosaic.IsMosaic[y, x] = true;
for (int i = x - yVariables.ImageMosaic.MosaicSize; i <= x + yVariables.ImageMosaic.MosaicSize; i++)
{
for (int j = y - yVariables.ImageMosaic.MosaicSize; j <= y + yVariables.ImageMosaic.MosaicSize; j++)
{
//边界考虑
if (i < 0) i = 0;
if (i >= mm.Width) i = mm.Width - 1;
if (j < 0) j = 0;
if (j >= mm.Height) j = mm.Height - 1;
//if (yVariables.ImageMosaic.IsMosaic[j, i] == false)
//{
yVariables.ImageMosaic.IsMosaic[j, i] = true;
OpenCvSharp.Vec3b color = new OpenCvSharp.Vec3b();
color.Item0 = (byte)(mm.Get<OpenCvSharp.Vec3b>(y, x).Item0);
color.Item1 = (byte)(mm.Get<OpenCvSharp.Vec3b>(y, x).Item1);
color.Item2 = (byte)(mm.Get<OpenCvSharp.Vec3b>(y, x).Item2);
mm.Set(j, i, color);
//}
}
}
Form1.Instance.pbxMosaic.Image = yImageConvert.MatToBitmap(mm);
}
Thread.Sleep(50);
}
else
{
yVariables.ImageMosaic.MosaicEvent.Reset();
yVariables.ImageMosaic.IsLeave = true;
yVariables.ImageMosaic.IsEnterPbx = false;
}
}
});
控件事件
//图像选择 初始变量
private void button1_Click_1(object sender, EventArgs e)
{
string path = yFileOperates.SelectPic();
if (path != "" && path != yVariables.ImageMosaic.Image)
{
yVariables.ImageMosaic.Image = path;
Bitmap map = new Bitmap(yVariables.ImageMosaic.Image);
pbxMosaic.Image = map;
tbxMosaiImage.Text = yVariables.ImageMosaic.Image;
yVariables.ImageMosaic.IsMosaic = new bool[map.Height, map.Width];
if(yImageMosaic.MosaicTask.IsAlive) yVariables.ImageMosaic.MosaicEvent.Reset();
for (int i = 0; i < map.Height; i++)
{
for (int j = 0; j < map.Width; j++)
{
yVariables.ImageMosaic.IsMosaic[i, j] = false;
}
}
}
}
//线程启动
private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
{
if (pbxMosaic.Image == null) return;
if (!yImageMosaic.MosaicTask.IsAlive)
yImageMosaic.MosaicTask.Start();
yVariables.ImageMosaic.IsLeave = false;
yVariables.ImageMosaic.IsEnterPbx = true;
yVariables.ImageMosaic.MosaicEvent.Set();
}
//暂停
private void pictureBox1_MouseUp(object sender, MouseEventArgs e)
{
yVariables.ImageMosaic.MosaicEvent.Reset();
}
private void pictureBox1_MouseLeave(object sender, EventArgs e)
{
if (yVariables.ImageMosaic.IsEnterPbx == true)
{
yVariables.ImageMosaic.IsEnterPbx = false;
yVariables.ImageMosaic.IsLeave = true;
yVariables.ImageMosaic.MosaicEvent.Reset();
}
}
刚开始运行起来的时候是正常的 但当在picturebox内一直按下鼠标时 再把鼠标移出picturebox 再回来时有时候就会不进线程,打断点也监测不到了,mousedown事件还是正常触发的,但是线程的isalive状态还是true的 。这种情况也是时而发生不确定什么原因造成的,而且发生后只能重启程序,更换图片都不行