在论坛中看到有网友提出关于 PictureBox 的问题,希望能实现一些简单的操作。
正好有空,写了段代码,发博+回复一举两得啦 :p
原本还准备加上负片、灰度、颜色替换等操作,但实现均不理想(对图像处理了解的太少)。
望专业人事能给点好的建议!
/* * 主要是对 PictureBox 的操作 * 截取屏幕图像 * 获取屏幕指定像素颜色 * 旋转和翻转图片 * 虚拟选择框绘制 * 控件绘图 * * 为了方便,所有步骤在一个方法中完成 * 创建了一个新的 Form 对象 * 在该 Form 中添加了一个 PictureBox 对象 */ // 在 Form_Load 中调用 private void CSDNSample_PictureBoxHandle() { // 复制屏幕,创建原始图片 Bitmap image = new Bitmap( Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height); using (Graphics g = Graphics.FromImage(image)) { g.CopyFromScreen( 0, 0, 0, 0, image.Size, CopyPixelOperation.SourceCopy); g.Save(); } // 创建 PictureBox 对象 PictureBox box = new PictureBox(); box.Location = new Point(0, 0); box.SizeMode = PictureBoxSizeMode.StretchImage; box.Size = image.Size; box.Image = image; // 创建 Form 对象 Form f = new Form(); f.AutoScroll = true; // 自动滚动 f.Size = new Size(800, 600); // From_FormClosed 用于释放资源 f.FormClosed += (sender, e) => { image.Dispose(); }; // From_MouseWheel 用于缩放图片 // 由于滚动条和缩放同时进行 会有点不爽 // 建议右键菜单或 Control/Shift/Alt + 鼠标滚轮组合实现 f.MouseWheel += (sender, e) => { if (e.Delta > 0) { // 限制放大效果 600% 以内 if (box.Width / image.Width < 6) { box.Size = new Size( (int)(box.Width * 1.1), (int)(box.Height * 1.1)); } } else { // 限制缩小效果 15% 以内 if ((float)box.Width / (float)image.Width > 0.15f) { box.Size = new Size( (int)(box.Width * 0.9), (int)(box.Height * 0.9)); } } }; // 用于记录鼠标按下时的位置 Point pt = Point.Empty; // PictureBox_MouseDown 用于记录鼠标位置 绘制屏幕十字标记 box.MouseDown += (sender, e) => { if (e.Button == MouseButtons.Left) { pt = e.Location; // Cursor.Position 获取全局鼠标位置(屏幕位置) // CopyFromScreen 拷贝 1 个屏幕像素并生成图片 // Bitmap.GetPixel 获取图片上指定像素的颜色 using (Bitmap bitmap = new Bitmap(1, 1)) { using (Graphics g = Graphics.FromImage(bitmap)) { g.CopyFromScreen( Cursor.Position.X, Cursor.Position.Y, 0, 0, bitmap.Size, CopyPixelOperation.SourceCopy); g.Save(); } // 设置窗口文本 // 显示鼠标当前位置和鼠标位置的像素颜色 Color color = bitmap.GetPixel(0, 0); f.Text = string.Format("Pos: {0}, Color: {1}", e.Location, color); } using (Graphics g = Graphics.FromHwnd(box.Handle)) { using (Pen p = new Pen(Color.IndianRed, 3)) { g.DrawLine( // 画十字图形的 X 轴 p, new Point(e.X - 10, e.Y), new Point(e.X + 10, e.Y)); g.DrawLine( // 画十字图形的 Y 轴 p, new Point(e.X, e.Y - 10), new Point(e.X, e.Y + 10)); } } } }; // PictureBox_MouseUp 用于清除鼠标位置信息和屏幕十字标记 box.MouseUp += (sender, e) => { if (e.Button == MouseButtons.Left) { pt = Point.Empty; box.Refresh(); } }; // PictureBox_MouseMove 用于绘制选择框 box.MouseMove += (sender, e) => { // 设置窗口文本 显示鼠标当前位置 f.Text = string.Format("Pos: {0}", e.Location); if (e.Button == MouseButtons.Left && pt != Point.Empty) { using (Graphics g = Graphics.FromHwnd(box.Handle)) { using (Pen p = new Pen(Color.IndianRed, 1)) { // pt1 用于判断鼠标是否离开了 PictureBox // 如果离开则重设 pt1 // 如此可保证被绘制的矩形一定出现在 PictureBox 中 Point pt1 = e.Location; if (pt1.X < 0) pt1.X = 0; if (pt1.Y < 0) pt1.Y = 0; if (pt1.X > box.Width - 1) pt1.X = box.Width - 1; if (pt1.Y > box.Height - 1) pt1.Y = box.Height - 1; box.Refresh(); // 不刷新的话 会出现N个矩形 p.DashStyle = System.Drawing.Drawing2D.DashStyle.Dash; g.DrawPolygon(p, new Point[] { pt, new Point (pt1.X, pt.Y), pt1, new Point(pt.X, pt1.Y) }); } } } }; // 记录当前翻转样式 int rotate = 0; // PictureBox_MouseDoubleClick 用于翻转图片 box.MouseDoubleClick += (sender, e) => { if (e.Button == MouseButtons.Left) { // 由于是对 PictureBox 进行的操作 // 图片只是进行了翻转,但大小未变 // 所以需要通过图片的某个边判断 // 图片是否因翻转而导致 Width / Height 互换 int imgWidth = box.Image.Width; box.Image.RotateFlip((RotateFlipType)rotate); if (++rotate > 7) rotate = 0; if (imgWidth == box.Image.Width) return; box.Size = new Size(box.Height, box.Width); } }; f.Controls.Add(box); f.Show(); }