C#開發執行個體-訂製螢幕剪取工具(四)基本截圖功能實現代碼

來源:互聯網
上載者:User

實現原理

基本的功能主要靠響應主表單的滑鼠按下、滑鼠移動、滑鼠抬起幾個事件的功能來實現的。截取的圖片地區使用“Label”組件來顯示,需要重新實現“Label”組件的“Paint”方法。

左鍵單擊開始,按右鍵取消,雙擊滑鼠左鍵完成,將截取的圖片儲存到Windows剪貼簿中。

添加“Label”組件

工具箱》公用組件》雙擊“Label”組件,修改組件屬性:

Name=lbl_CutImage,

AutoSize=False,

BackColor=Transparent,

Text = “”

“Form1_Load”事件添加代碼:

this.lbl_CutImage.Hide();

定義功能依賴的基本變數

        #region 基本變數        /// <summary>        /// 用於判斷是否已經開始,控制資訊框是否顯示。        /// </summary>        private bool isCuting;        /// <summary>        /// 滑鼠按下的點        /// </summary>        private Point beginPoint;        /// <summary>        /// 最終確定的繪圖基點        /// </summary>        private Point endPoint;        /// <summary>        /// 用於記錄顯示地區的大小(包括調整塊的地區,調整地區邊框寬度2px)        /// </summary>        private Rectangle cutImageRect = new Rectangle(0, 0, 5, 5);        #endregion

定義枚舉類型:更新UI的模式

        /// <summary>        /// 更新UI的模式,用於標記哪些需要顯示,哪些需要隱藏;        /// </summary>        [FlagsAttribute]        public enum UpdateUIMode : uint        {            //值得注意的是,如果要使用組合值,那麼就不能用串連的數字表示,必須是幾何級增長!            None = 0,            ShowTextPro = 1,            ShowPenStyle = 2,            ShowToolBox = 4,            ShowInfoBox = 8,            ShowZoomBox = 16,            ShowCutImage = 32,            HideTextPro = 64,            HidePenStyle = 128,            HideToolBox = 256,            HideInfoBox = 512        }

添加方法:計算並儲存的地區框的大小

        /// <summary>        /// 計算並儲存的地區框的大小        /// </summary>        private void SaveCutImageSize(Point beginPoint, Point endPoint)        {            // 儲存最終的繪圖基點,用於截取選中的地區            this.endPoint = beginPoint;            // 計算截取圖片的大小            int imgWidth = Math.Abs(endPoint.X - beginPoint.X) + 1;            int imgHeight = Math.Abs(endPoint.Y - beginPoint.Y) + 1;            int lblWidth = imgWidth + 4;            int lblHeight = imgHeight + 4;            // 設定地區的位置和大小            this.cutImageRect = new Rectangle(beginPoint.X - 2, beginPoint.Y - 2, lblWidth, lblHeight);        }

添加方法:執行,將選定地區的圖片儲存到剪貼簿

        /// <summary>        /// 執行,將選定地區的圖片儲存到剪貼簿        /// </summary>        /// <param name="saveToDisk">        /// 是否將圖片儲存到磁碟        /// </param>        private void ExecCutImage(bool saveToDisk, bool uploadImage) //bool saveToDisk = false, bool uploadImage = false        {            // 如果圖片擷取地區不可見,則退出儲存圖片過程            if (!this.lbl_CutImage.Visible) { return; }            Rectangle srcRect = new Rectangle();            srcRect.X = this.lbl_CutImage.Location.X + 2;            srcRect.Y = this.lbl_CutImage.Location.Y + 2;            srcRect.Width = this.lbl_CutImage.Width - 4;            srcRect.Height = this.lbl_CutImage.Height - 4;            Rectangle destRect = new Rectangle(0, 0, srcRect.Width, srcRect.Height);            Bitmap bmp = new Bitmap(srcRect.Width, srcRect.Height);            Graphics g = Graphics.FromImage(bmp);            g.DrawImage(this.screenImage, destRect, srcRect, GraphicsUnit.Pixel);            Clipboard.SetImage(bmp);            ExitCutImage(true);        }

添加方法:退出過程

       /// <summary>        /// 退出過程        /// </summary>        private void ExitCutImage(bool hideWindow) //  = true        {            this.lbl_CutImage.Visible = false;            this.isCuting = false;            if (hideWindow)            {                this.screenImage.Dispose();                this.Hide();            }        }

主視窗滑鼠按下事件處理常式

        /// <summary>        /// 視窗滑鼠按下事件處理常式        /// </summary>        /// <param name="sender"></param>        /// <param name="e"></param>        private void Form1_MouseDown(object sender, MouseEventArgs e)        {            // 左鍵單擊事件            if (e.Button == MouseButtons.Left && e.Clicks == 1)            {                if (!this.lbl_CutImage.Visible)                {                    this.isCuting = true;                    this.beginPoint = e.Location;                    this.endPoint = e.Location;                    SaveCutImageSize(e.Location, e.Location);                    UpdateCutInfoLabel(UpdateUIMode.ShowCutImage | UpdateUIMode.ShowInfoBox);                }            }            // 左鍵雙擊事件            if (e.Button == MouseButtons.Left && e.Clicks == 2)            {                if (this.lbl_CutImage.Visible)                {                    ExecCutImage(false, false);                }            }            // 按右鍵事件            if (e.Button == MouseButtons.Right)            {                ExitCutImage(!this.lbl_CutImage.Visible);            }        }

主視窗滑鼠移動事件處理常式

        /// <summary>        /// 視窗滑鼠移動事件處理常式        /// </summary>        /// <param name="sender"></param>        /// <param name="e"></param>        private void Form1_MouseMove(object sender, MouseEventArgs e)        {            // 如果截取地區不可見,則退出處理過程            if (!this.lbl_CutImage.Visible)            {                UpdateCutInfoLabel(UpdateUIMode.None);                return;            }            Point pntBgn = this.beginPoint;            Point pntEnd = e.Location;            // 如果是反向拖動,重新設定起始點            if (e.Location.X < this.beginPoint.X && e.Location.Y < this.beginPoint.Y)            {                pntBgn = e.Location;                pntEnd = this.beginPoint;            }            else            {                if (e.Location.X < this.beginPoint.X)                {                    pntBgn = new Point(e.Location.X, this.beginPoint.Y);                    pntEnd = new Point(this.beginPoint.X, e.Location.Y);                }                else                {                    if (e.Location.Y < this.beginPoint.Y)                    {                        pntBgn = new Point(this.beginPoint.X, e.Location.Y);                        pntEnd = new Point(e.Location.X, this.beginPoint.Y);                    }                }            }            if (this.isCuting)            {                SaveCutImageSize(pntBgn, pntEnd);            }            UpdateCutInfoLabel(UpdateUIMode.None);        }

主視窗滑鼠抬起事件處理常式

        /// <summary>        /// 視窗滑鼠抬起事件處理常式        /// </summary>        /// <param name="sender"></param>        /// <param name="e"></param>        private void Form1_MouseUp(object sender, MouseEventArgs e)        {            if (e.Button == MouseButtons.Left)            {                if (this.isCuting)                {                    this.isCuting = false;                    UpdateCutInfoLabel(UpdateUIMode.None);                }            }        }

截取地區圖片繪製

        /// <summary>        /// 截取地區圖片的繪製事件處理常式        /// </summary>        /// <param name="sender"></param>        /// <param name="e"></param>        private void lbl_CutImage_Paint(object sender, PaintEventArgs e)        {            int imgWidth = this.lbl_CutImage.Width - 4;            int imgHeight = this.lbl_CutImage.Height - 4;            if (imgWidth < 1) { imgWidth = 1; }            if (imgHeight < 1) { imgHeight = 1; }            // 建立緩衝映像,先將要繪製的內容全部繪製到緩衝中,最後再一次性繪製到 Label 上,            // 這樣可以提高效能,並且可以防止螢幕閃爍的問題            Bitmap bmp_lbl = new Bitmap(this.lbl_CutImage.Width, this.lbl_CutImage.Height);            Graphics g = Graphics.FromImage(bmp_lbl);            // 將要截取的部分繪製到緩衝            Rectangle destRect = new Rectangle(2, 2, imgWidth, imgHeight);            Point srcPoint = this.lbl_CutImage.Location;            srcPoint.Offset(2, 2);            Rectangle srcRect = new Rectangle(srcPoint, new System.Drawing.Size(imgWidth, imgHeight));            g.DrawImage(this.screenImage, destRect, srcRect, GraphicsUnit.Pixel);            SolidBrush brush = new SolidBrush(Color.FromArgb(10, 124, 202));            Pen pen = new Pen(brush, 1.0F);            //以下部分(邊框和調整塊)的繪製放在(編輯內容)的後面,是解決繪製編輯內容會覆蓋(邊框和調整塊)的問題            // 繪製邊框外的地區,解決會被編輯內容覆蓋的問題            // 上邊            destRect = new Rectangle(0, 0, this.lbl_CutImage.Width, 2);            srcPoint = this.lbl_CutImage.Location;            //srcPoint.Offset(2, 2);            srcRect = new Rectangle(srcPoint, new System.Drawing.Size(this.lbl_CutImage.Width, 2));            g.DrawImage(this.BackgroundImage, destRect, srcRect, GraphicsUnit.Pixel);            // 下邊            destRect = new Rectangle(0, this.lbl_CutImage.Height - 2, this.lbl_CutImage.Width, 2);            srcPoint = this.lbl_CutImage.Location;            srcPoint.Offset(0, this.lbl_CutImage.Height - 2);            srcRect = new Rectangle(srcPoint, new System.Drawing.Size(this.lbl_CutImage.Width, 2));            g.DrawImage(this.BackgroundImage, destRect, srcRect, GraphicsUnit.Pixel);            // 左邊            destRect = new Rectangle(0, 2, 2, this.lbl_CutImage.Height - 4);            srcPoint = this.lbl_CutImage.Location;            srcPoint.Offset(0, 2);            srcRect = new Rectangle(srcPoint, new System.Drawing.Size(2, this.lbl_CutImage.Height - 4));            g.DrawImage(this.BackgroundImage, destRect, srcRect, GraphicsUnit.Pixel);            // 右邊            destRect = new Rectangle(this.lbl_CutImage.Width - 2, 2, 2, this.lbl_CutImage.Height - 4);            srcPoint = this.lbl_CutImage.Location;            srcPoint.Offset(this.lbl_CutImage.Width - 2, 2);            srcRect = new Rectangle(srcPoint, new System.Drawing.Size(2, this.lbl_CutImage.Height - 4));            g.DrawImage(this.BackgroundImage, destRect, srcRect, GraphicsUnit.Pixel);            // 繪製邊框            g.DrawLine(pen, 2, 2, this.lbl_CutImage.Width - 3, 2);            g.DrawLine(pen, 2, 2, 2, this.lbl_CutImage.Height - 3);            g.DrawLine(pen, this.lbl_CutImage.Width - 3, 2, this.lbl_CutImage.Width - 3, this.lbl_CutImage.Height - 3);            g.DrawLine(pen, 2, this.lbl_CutImage.Height - 3, this.lbl_CutImage.Width - 3, this.lbl_CutImage.Height - 3);            // 繪製四個角的調整塊            g.FillRectangle(brush, 0, 0, 4, 5);            g.FillRectangle(brush, this.lbl_CutImage.Width - 4, 0, 4, 5);            g.FillRectangle(brush, 0, this.lbl_CutImage.Height - 5, 4, 5);            g.FillRectangle(brush, this.lbl_CutImage.Width - 4, this.lbl_CutImage.Height - 5, 4, 5);            // 繪製中間的四個調整塊            int blockX = this.lbl_CutImage.Width / 2 - 2;            int blockY = this.lbl_CutImage.Height / 2 - 2;            g.FillRectangle(brush, blockX, 0, 4, 5);            g.FillRectangle(brush, 0, blockY, 4, 5);            g.FillRectangle(brush, blockX, this.lbl_CutImage.Height - 5, 4, 5);            g.FillRectangle(brush, this.lbl_CutImage.Width - 4, blockY, 4, 5);            // 繪製到 Label 上            e.Graphics.DrawImage(bmp_lbl, 0, 0);            bmp_lbl.Dispose();        }

雙擊滑鼠左鍵完成功能

        /// <summary>        /// 截取地區圖片的滑鼠按下事件處理常式        /// </summary>        /// <param name="sender"></param>        /// <param name="e"></param>        private void lbl_CutImage_MouseDown(object sender, MouseEventArgs e)        {            // 左鍵雙擊事件            if (e.Button == MouseButtons.Left && e.Clicks == 2)            {                if (this.lbl_CutImage.Visible)                {                    ExecCutImage(false, false);                }            }        }

注意:代碼都貼完了,別忘了為表單或組件綁定事件處理常式;

例如:截取地區圖片的滑鼠按下事件處理常式“lbl_CutImage_MouseDown”,就是“lbl_CutImage”組件的“MouseDown”事件的處理常式,Binder 方法參考:


到此,基本的功能實現已經實現,趕快去截取一張圖片,粘貼到QQ的聊天視窗看看吧。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.