C#实现全屏幕截图

发布时间:2017-09-30编辑:佚名阅读(1488)

    1.实现思路如下:1. 开始截图时,创建一个与屏幕大小一样的位图,然后用Graphics.CopyFromScreen()把屏幕位图拷贝到该位图上。这是很关键的一步,这样所有的操作就都可以在该位图上进行了,而无实际屏幕无关了。 

    int width = Screen.PrimaryScreen.Bounds.Width;
    int height = Screen.PrimaryScreen.Bounds.Height;
    Bitmap bmp = new Bitmap(width, height);
    using (Graphics g = Graphics.FromImage(bmp))
    {
        g.CopyFromScreen(0, 0, 0, 0, new Size(width, height));
    }


    2. 接下来为了方便在这之上进行截图,有一个很重要的设计实现方式:用全屏幕窗体代替现有真实屏幕,这样就可以把截图过程的所有操作都在那个窗体上实现(该窗体设置成无边框,高宽等于屏幕大小即可),另外为了显示掩蔽效果(只能正常显示选择的部分屏幕内容,而其实部分用一个如半透明层覆盖),就添加一层半透明位置位图。具体代码如下:

public partial class FullScreenForm : Form
    {
        private Rectangle rectSelected = Rectangle.Empty;
        private bool isClipping = false;
        private Bitmap screen;
        private Bitmap coverLayer = null;
        private Color coverColor;
        private Brush rectBrush = null;
        private Bitmap resultBmp = null;
        int xx, yy;
        public FullScreenForm(Bitmap screen)
        {
            InitializeComponent();
            int width = Screen.PrimaryScreen.Bounds.Width;
            int height = Screen.PrimaryScreen.Bounds.Height;
            coverLayer = new Bitmap(width, height);
            coverColor = Color.FromArgb(50, 200, 0, 0);
            rectBrush = new SolidBrush(coverColor);
            using (Graphics g = Graphics.FromImage(coverLayer))
            {
                g.Clear(coverColor);
            }
            this.Bounds = new Rectangle(0, 0, width, height);
            this.screen = screen;
            this.DoubleBuffered = true;
        }
        protected override void OnMouseDown(MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                isClipping = true;
                rectSelected.Location = e.Location;
                xx = e.X;
                yy = e.Y;
            }
            else if (e.Button == MouseButtons.Right)
            {
                this.DialogResult = DialogResult.OK;
            }
        }
        protected override void OnMouseMove(MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left && isClipping)
            {
                rectSelected.Width = Math.Abs(e.X - xx);
                if (e.X < xx)
                {
                    rectSelected.X = e.X;
                }
                else
                {
                    rectSelected.X = xx;
                }
                rectSelected.Height = Math.Abs(e.Y - yy);
                if (e.Y < yy)
                {
                    rectSelected.Y = e.Y;
                }
                else
                {
                    rectSelected.Y = yy;
                }
                this.Invalidate();
            }
        }
        protected override void OnMouseUp(MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left && isClipping)
            {
                rectSelected.Width = Math.Abs(e.X - xx);
                if (e.X < xx)
                {
                    rectSelected.X = e.X;
                }
                else
                {
                    rectSelected.X = xx;
                }
                rectSelected.Height = Math.Abs(e.Y - yy);
                if (e.Y < yy)
                {
                    rectSelected.Y = e.Y;
                }
                else
                {
                    rectSelected.Y = yy;
                }
                this.Invalidate();
                if (rectSelected.Width == 0 || rectSelected.Height == 0)
                {
                    return;
                }
                resultBmp = new Bitmap(rectSelected.Width, rectSelected.Height);
                using (Graphics g = Graphics.FromImage(resultBmp))
                {
                    g.DrawImage(screen, new Rectangle(0, 0, rectSelected.Width, rectSelected.Height), rectSelected, GraphicsUnit.Pixel);
                }
                this.DialogResult = DialogResult.OK;
            }
        }
        protected override void OnPaint(PaintEventArgs e)
        {
            Graphics g = e.Graphics;
            g.DrawImage(screen, 0, 0);
            g.DrawImage(coverLayer, 0, 0);
            PaintRectangle();
        }
        protected override void OnPaintBackground(PaintEventArgs e)
        {
        }
        protected override void OnKeyDown(KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Escape)
            {
                this.DialogResult = DialogResult.Cancel;
            }
        }
        private void PaintRectangle()
        {
            using (Graphics g = Graphics.FromImage(coverLayer))
            {
                g.Clear(coverColor);
                GraphicsPath path = new GraphicsPath();
                path.AddRectangle(this.Bounds);
                path.AddRectangle(rectSelected);
                g.FillPath(rectBrush, path);
                g.DrawRectangle(Pens.Blue, rectSelected);
            }
        }
        public Bitmap ResultBitmap
        {
            get 
            { 
                return resultBmp; 
            }
        }
    }


    上面的代码都很容易看明白,这里有一个技巧就是GraphicsPath,它自动会形成一个中空的区域。上面的实现很容易扩展:多区域截图,多裁判截图等都很容易实现。

    关键字: C# 全屏幕截图


鼓掌

0

正能量

0

0

呵呵

1


评论区