C#关于制作截图工具(一)<简单截图>

长平狐 发布于 2012/12/10 17:21
阅读 2K+
收藏 0
记得我以前开始想做截图工具的时候 在网上看了n多 虽然网上有很多这类文章 不过当时我感觉我看的那些文章对于我来说“太华丽”了有点

因为网上看的那些都是做的一整个截图工具上面包含了很多功能 比如可以话箭头 画一个矩形什么的 并且那个时候也才借出GDI的一点东西 所以看着代码特别头痛

其实在看的过程中 我正在关心的不是怎么在上面画一个箭头而是关心的怎么把图给截下来的 现在我截图都还不会 画箭头有什么用?

所以考虑到这个问题 我也来发表发表(淡定、、) 先从一个很简陋的版本开始慢慢的把功能弄上去

这个是第一个版本的源码

http://download.csdn.net/detail/crystal_lz/4110186

 

呃呃、、先说一下其实我也是一个菜鸟、、所以有什么地方说的不对的(你懂得、、、)

 

首先截图的时候第一步要做的就是把整个屏幕弄下来

 public Bitmap GetScreen() {//获取整个屏幕图像
            Bitmap bmp = new Bitmap(this.Width, this.Height);
            using (Graphics g = Graphics.FromImage(bmp)) {
                g.CopyFromScreen(0, 0, 0, 0, this.Size);
            }
            return bmp;
        }

写一个方法就搞定了首先创建一个位图对象 Graphics g = Graphics.FromImage(bmp) 那么这个g是直接对bmp进行操作 CopyFromScreen 方法可以得到当前屏幕

g.CopyFormScreen(0,0,0,0,this.Size)是直接的把这个屏幕保存到bmp中去 前面两个是坐标 是这个全屏的图像在bmp里面的左上角位置(现在bmp是画布)后面两个0是要从全屏图像上的什么位置开始截取 最后一个是截取的大小

 

private void Form2_Load(object sender, EventArgs e) {
            //保存按钮的位置
            button1.Location = new Point(this.Width - button1.Width, this.Height - button1.Height);
            screenBmp = GetScreen();//获取屏幕图像保存到screenBmp中
            pictureBox1.Image = GetScreen();//获取全屏图像到图片框中
            using (Graphics g = Graphics.FromImage(pictureBox1.Image)) {//这一步是在图片上面填充一层半透明黑色(QQ截图那种)
                using (SolidBrush sb = new SolidBrush(Color.FromArgb(125, 0, 0, 0))) {
                    g.FillRectangle(sb, 0, 0, this.Width, this.Height);//填充整个窗体
                }
            }
        }


 窗体一加载的时候就把屏幕的图像加载到窗体中其中 button1是保存按钮(呃、、好吧这个东西我承认不该放到哪里  是要像qq那样拉出一个区域后显示一个工具条出来的什么的就自己看着办吧 这里只是为了演示)

screenBmp 是声明的一个全局的Bitmap对象用来保存全屏的图像的 然后pictureBox也获取一个全屏图像(因为要把它弄黑)Graphics g = Graphics.FromImage(pictureBox1.Image)直接在pictrueBox上面的图片操作

SolidBrush sb = new SolidBrush(Color.FromArgb(125, 0, 0, 0))创建一个刷笔Color.FromArgb(125, 0, 0, 0) 这个是半透明的黑色 (好吧不是半透明 只是我觉得125习惯一点)

g.FillRectangle(sb, 0, 0, this.Width, this.Height) 用那个刷笔填充那个pictureBox里面的图片 那两个0是要从什么位置开始填充 后面两个是大小

好了 现在窗体出来的时候 你就可以看到qq截图一样的效果了 屏幕略带黑色 然后就是在上面拖出一个区域了

pictureBox的三个事件 mouseDown MouseMove mouseUp

Down的时候就表示要在上面拖出一个区域了 所以并且点下鼠标的时候 那个地方就是一个 要绘制的区域的一个顶点所以 这个时候 须要记录两个信息 鼠标的坐标 和 告诉程序我要绘制区域啦、、、

        int sx, sy;//鼠标点下时候的坐标信息
        int w, h;//拉出来的区域大小
        bool isDrawRect;//时候在窗体上绘制矩形
        private void pictureBox1_MouseDown(object sender, MouseEventArgs e) {
            sx = MousePosition.X;//记录当前鼠标坐标信息
            sy = MousePosition.Y;
            isDrawRect = true;//鼠标点下是绘制矩形
            w = h = 0;
        }

然后是move事件 move的时候就在上面绘制一个区域出来 但是绘制的时候要判断现在是否是鼠标已经点下 鼠标点下才能拉动出一个区域来 而且是鼠标点下的那个点固定和当前的鼠标位置绘制一个巨型出来

private void pictureBox1_MouseMove(object sender, MouseEventArgs e) {
            if (!isDrawRect) {//如果不允许绘制 直接返回
                return;
            }
            pictureBox1.Refresh();//刷新窗体(主要是在move事件里面在不停绘制绘制一次刷新一次(上次绘制的就被清除了))
            using (Graphics g = pictureBox1.CreateGraphics()) {
                using (Pen p = new Pen(Color.FromArgb(255, 24, 215, 255))) {//创建画笔
                    w = MousePosition.X - sx;//当前鼠标x坐标减去点下鼠标时的x坐标就是宽度(注意负数)
                    h = MousePosition.Y - sy;
                    g.DrawRectangle(p, sx, sy, w, h);//绘制矩形
                }
            }
        }

这里是Graphics g = pictureBox1.CreateGraphics()是直接将pictureBox控件作为画布进行画图而不是pictureBox里面的图片(画巨型)- -!、、还有 我这个地方没有考虑反方向拉动、、、、我怕写了后代码看起来杂乱、、、

还有 这里用了pen画笔和前面的那个刷笔不一样 刷笔是用来填充的 pen是线条(呃 暂时就这样理解吧)呃 悲剧了Pen p = new Pen(Color.FromArgb(255, 24, 215, 255),1)貌似源文件里面不是这样写的  后面那个参数 是画笔的大小 要是没有写的话就是1个像素大小

然后是Up Up的时候要告诉程序停止绘制矩形了  并且把刚才绘制的那个区域的图像绘制出来(也就是绘制成没有填充黑色的那个)

        private void pictureBox1_MouseUp(object sender, MouseEventArgs e) {
            isDrawRect = false;// 鼠标抬起禁止绘制矩形 并且把矩形区域的图像绘制出来
            using (Graphics g = pictureBox1.CreateGraphics()) { 
                Rectangle destRect = new Rectangle(sx,sy,w + 1,h + 1);//在画布上要显示的区域(记得像素加1)
                Rectangle srcRect = new Rectangle(sx,sy,w + 1,h + 1);//图像上要截取的区域
                g.DrawImage(screenBmp, destRect, srcRect, GraphicsUnit.Pixel);//加图像绘制到画布上
            }
        }

好吧我承认qq的那个是在绘制矩形的过程中就把边把那个区域的图像弄出来了 如果把这句代码搬到move里面也可以绘制矩形的时候就一边绘制这部分图像(很闪 因为Refresh()在不停的刷新 其实我做的(不是这个)是用的两个窗体来完成的后面再说这个)
这部分弄出来后 就该保存了(- -!、、、屏幕右下角的那个按钮(只能说悲催的一直在那里))

        private void button1_Click(object sender, EventArgs e) {
            SaveFileDialog saveBmp = new SaveFileDialog();
            saveBmp.Filter = "bmp格式|*.bmp|jpg格式|*.jpg";//过滤器
            saveBmp.FileName = "截图";//默认名字
            saveBmp.ShowDialog();//弹出对话框
            if (saveBmp.FileName != "") {
                Bitmap Bmp = new Bitmap(w + 1, h + 1);//创建新图像(因为刚才那个是直接在窗体上绘制的 保存的时候根据坐标重新绘制一下)
                using (Graphics g = Graphics.FromImage(Bmp)) {
                    Rectangle destRect = new Rectangle(0, 0, w + 1, h + 1);//在画布上要显示的区域
                    Rectangle srcRect = new Rectangle(sx, sy, w + 1, h + 1);//要截取的图像上面的区域
                    g.DrawImage(screenBmp, destRect, srcRect, GraphicsUnit.Pixel);//在screenBmp上截取图像保存到bmp中
                    if (saveBmp.FilterIndex == 0) {//判断选中的什么格式 然后保存
                        Bmp.Save(saveBmp.FileName, System.Drawing.Imaging.ImageFormat.Bmp);
                    } else {
                        Bmp.Save(saveBmp.FileName, System.Drawing.Imaging.ImageFormat.Jpeg);
                    }
                }
            }
            this.Close();
        }

好吧解释一下 刚才虽然 鼠标抬起的时候 就把那部分绘制出来了 不过是绘制在pictureBox控件上面的并没有把这个图像保存到什么里面

反正都有刚才的坐标信息 在重新绘制一次就行了并且保存到bmp里面 在调用bmp的save方法保存图像、、、

 

- -!、、好吧 这个超级简陋而且n多bug的截图工具就到这里了、、、有时间的话再把他功能弄一弄再继续发表、、、、

        private void pictureBox1_MouseUp(object sender, MouseEventArgs e) {
            isDrawRect = false;// 鼠标抬起进制绘制矩形 并且把矩形区域的图像绘制出来
            using (Graphics g = pictureBox1.CreateGraphics()) { 
                Rectangle destRect = new Rectangle(sx,sy,w + 1,h + 1);//在画布上要显示的区域(记得像素加1)
                Rectangle srcRect = new Rectangle(sx,sy,w + 1,h + 1);//图像上要截取的区域
                g.DrawImage(screenBmp, destRect, srcRect, GraphicsUnit.Pixel);//加图像绘制到画布上
            }
        }

 


原文链接:http://blog.csdn.net/crystal_lz/article/details/7316517
加载中
返回顶部
顶部