<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12
      【Talk is cheap. Show me the code.】 公眾號如有回復不及時的,麻煩點擊聯(lián)系關于我-聯(lián)系博主,微信我。謝謝!
      老帥哥

      Stephen-kzx的博客

      【Talk is cheap. Show me the code.】【公眾號如有回復不及時的,麻煩點擊聯(lián)系關于我-聯(lián)系博主,微信我。謝謝!】

      c#造個輪子--GIF錄制工具

              在以往幾篇文章里面,大家都可以看到各種錄制的GIF效果圖,把gif放在文章開始,不僅可以減少很多冗余的解釋白話文,更可以讓讀者一覽無余看到文章大概要義。

      以往都是使用“LicEcap”來錄制的,那么我們是否能自己實現一個這樣的工具呢?一方面國慶假期結束,練練代碼手感,另一方面可以根據自己需求擴展需要的功能。

       

      01介紹軟件UI及操作

      操作比較簡單,以下是運行界面:

      1. 選擇錄制區(qū)域,繪制需要錄制的ROI區(qū)域 

      2. 點擊開始錄制

      3. 錄制結束后,停止錄制即可.彈出保存路徑保存gif

       

      image.png

      02效果圖

      1. 整個運行作業(yè)圖

        test.gif

      2. 實際錄屏的ROI區(qū)域效果GIF

        eee.gif

      03源碼介紹

      image

       

      private void InitializeComponents()
      {
          this.Text = "GIF錄制工具";
          this.Size = new Size(400, 200);
          this.StartPosition = FormStartPosition.CenterScreen;

          // 選擇區(qū)域按鈕
          Button btnSelectArea = new Button();
          btnSelectArea.Text = "選擇錄制區(qū)域";
          btnSelectArea.Size = new Size(120, 30);
          btnSelectArea.Location = new Point(20, 20);
          btnSelectArea.Click += BtnSelectArea_Click;
          this.Controls.Add(btnSelectArea);

          // 開始錄制按鈕
          Button btnStart = new Button();
          btnStart.Text = "開始錄制";
          btnStart.Size = new Size(120, 30);
          btnStart.Location = new Point(20, 60);
          btnStart.Click += BtnStart_Click;
          this.Controls.Add(btnStart);

          // 停止錄制按鈕
          Button btnStop = new Button();
          btnStop.Text = "停止錄制";
          btnStop.Size = new Size(120, 30);
          btnStop.Location = new Point(20, 100);
          btnStop.Click += BtnStop_Click;
          this.Controls.Add(btnStop);

          // 幀率選擇
          Label lblFrameRate = new Label();
          lblFrameRate.Text = "幀率:";
          lblFrameRate.Location = new Point(160, 65);
          lblFrameRate.Size = new Size(50, 20);
          this.Controls.Add(lblFrameRate);

          NumericUpDown numFrameRate = new NumericUpDown();
          numFrameRate.Value = frameRate;
          numFrameRate.Minimum = 1;
          numFrameRate.Maximum = 30;
          numFrameRate.Location = new Point(210, 65);
          numFrameRate.Size = new Size(60, 20);
          numFrameRate.ValueChanged += (s, e) => { frameRate = (int)numFrameRate.Value; };
          this.Controls.Add(numFrameRate);

          // 狀態(tài)標簽
          Label lblStatus = new Label();
          lblStatus.Text = "狀態(tài): 就緒";
          lblStatus.Location = new Point(160, 25);
          lblStatus.Size = new Size(200, 20);
          lblStatus.Name = "lblStatus";
          this.Controls.Add(lblStatus);

          // 錄制計時器
          captureTimer = new System.Windows.Forms.Timer();
          captureTimer.Tick += CaptureTimer_Tick;
      }

      選擇ROI錄屏區(qū)域

      private void StartAreaSelection()
      {
          this.Hide();
          Thread.Sleep(500); // 等待窗體隱藏

          isSelectingArea = true;
          Cursor = Cursors.Cross;

          // 創(chuàng)建全屏透明窗體用于區(qū)域選擇
          Form selectionForm = new Form();
          selectionForm.WindowState = FormWindowState.Maximized;
          selectionForm.FormBorderStyle = FormBorderStyle.None;
          selectionForm.BackColor = Color.Black;
          selectionForm.Opacity = 0.3;
          selectionForm.TopMost = true;
          selectionForm.Cursor = Cursors.Cross;

          Rectangle selectedArea = Rectangle.Empty;
          bool isDragging = false;
          Point dragStart = Point.Empty;

          selectionForm.MouseDown += (s, e) =>
          {
              if (e.Button == MouseButtons.Left)
              {
                  isDragging = true;
                  dragStart = e.Location;
              }
          };

          selectionForm.MouseMove += (s, e) =>
          {
              if (isDragging)
              {
                  int x = Math.Min(dragStart.X, e.X);
                  int y = Math.Min(dragStart.Y, e.Y);
                  int width = Math.Abs(e.X - dragStart.X);
                  int height = Math.Abs(e.Y - dragStart.Y);

                  selectedArea = new Rectangle(x, y, width, height);
                  selectionForm.Invalidate();
              }
          };

          selectionForm.MouseUp += (s, e) =>
          {
              if (e.Button == MouseButtons.Left && isDragging)
              {
                  isDragging = false;
                  if (selectedArea.Width > 10 && selectedArea.Height > 10)
                  {
                      recordingArea = selectedArea;
                      UpdateStatus($"已選擇區(qū)域: {recordingArea}");
                  }
                  selectionForm.Close();
              }
          };

          selectionForm.Paint += (s, e) =>
          {
              if (isDragging && !selectedArea.IsEmpty)
              {
                  using (Pen pen = new Pen(Color.Red, 2))
                  {
                      e.Graphics.DrawRectangle(pen, selectedArea);
                  }

                  string sizeText = $"{selectedArea.Width} x {selectedArea.Height}";
                  using (Font font = new Font("Arial", 12))
                  using (Brush brush = new SolidBrush(Color.Red))
                  {
                      e.Graphics.DrawString(sizeText, font, brush, selectedArea.X, selectedArea.Y - 20);
                  }
              }
          };

          selectionForm.KeyDown += (s, e) =>
          {
              if (e.KeyCode == Keys.Escape)
              {
                  selectionForm.Close();
              }
          };

          selectionForm.FormClosed += (s, e) =>
          {
              isSelectingArea = false;
              Cursor = Cursors.Default;
              this.Show();
              this.BringToFront();
          };

          selectionForm.ShowDialog();
      }

      錄制結束,保存GIF

      private void SaveGif()
       {
           if (frames.Count == 0)
           {
               MessageBox.Show("沒有可保存的幀!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
               return;
           }

           using (SaveFileDialog saveDialog = new SaveFileDialog())
           {
               saveDialog.Filter = "GIF 文件|*.gif";
               saveDialog.Title = "保存GIF文件";
               saveDialog.DefaultExt = "gif";

               if (saveDialog.ShowDialog() == DialogResult.OK)
               {
                   try
                   {
                       // 使用GifBitmapEncoder替代方案
                       SaveFramesAsGif(frames, saveDialog.FileName, frameRate);
                       MessageBox.Show($"GIF保存成功!\n文件: {saveDialog.FileName}\n幀數: {frames.Count}", "成功",
                           MessageBoxButtons.OK, MessageBoxIcon.Information);
                   }
                   catch (Exception ex)
                   {
                       MessageBox.Show($"保存GIF時出錯: {ex.Message}", "錯誤", MessageBoxButtons.OK, MessageBoxIcon.Error);
                   }
               }
           }

           // 清理資源
           foreach (var frame in frames)
           {
               frame.Dispose();
           }
           frames.Clear();
       }
      private void SaveFramesAsGif(List<Bitmap> frames, string filePath, int frameRate)
       {
           using (var collection = new MagickImageCollection())
           {
               foreach (var frame in frames)
               {
                   using (var memoryStream = new MemoryStream())
                   {
                       frame.Save(memoryStream, ImageFormat.Bmp);
                       memoryStream.Position = 0;

                       var image = new MagickImage(memoryStream);
                       image.AnimationDelay =Convert.ToUInt32( 100 / frameRate); // 設置幀延遲
                       collection.Add(image);
                   }
               }

               // 優(yōu)化GIF
               collection.Optimize();
               collection.Write(filePath);
           }
       }

      主要用到第三方nuget包

      1. AnimatedGif

      2. Magick.NET-Q16-AnyCPU

      結束語

        感謝各位耐心查閱!  如果您有更好的想法歡迎一起交流,有不懂的也可以微信公眾號聯(lián)系博主,作者公眾號會經常發(fā)一些實用的小工具和demo源碼,需要的可以去看看!另外,如果覺得本篇博文對您或者身邊朋友有幫助的,麻煩點個關注!贈人玫瑰,手留余香,您的支持就是我寫作最大的動力,感謝您的關注,期待和您一起探討!再會!

      image

       

      posted @ 2025-10-07 18:39  何以解憂唯有*碼  閱讀(1193)  評論(8)    收藏  舉報
      主站蜘蛛池模板: 欧美大屁股xxxx高跟欧美黑人| 亚洲一区久久蜜臀av| 三上悠亚在线精品二区| 又大又粗欧美黑人aaaaa片| 永久免费av网站可以直接看的 | 玩弄美艳馊子高潮无码| 亚洲成人av免费一区| 香蕉影院在线观看| 亚洲综合一区二区三区在线| 国产日韩综合av在线| 成熟丰满熟妇av无码区| 久久99日本免费国产精品| 亚洲中文字幕久久精品码| 日韩大片高清播放器| 日本边添边摸边做边爱| 久久国产精品伊人青青草| 精品一区二区三区东京热| 久久夜色噜噜噜亚洲av| 亚洲色成人一区二区三区| 国产精品毛片无遮挡高清| 成人精品日韩专区在线观看| 免费人成网站免费看视频| 在线天堂中文www官网| 国产成人精品久久性色av| 国产成人AV性色在线影院| 欧美人成精品网站播放| 亚洲伊人久久综合影院| 亚洲免费一区二区av| 人摸人人人澡人人超碰97| 亚洲大尺度一区二区三区| 夜夜躁狠狠躁2021| 亚洲精品日本一区二区| 欧美精品一区二区三区中文字幕| 无码人妻一区二区三区免费N鬼沢 亚洲国产精品自产在线播放 | 国产女人喷潮视频免费| 久久99国内精品自在现线| 久久夜色精品国产亚洲a| 狠狠综合久久av一区二| 国产日韩av一区二区在线| 亚洲夂夂婷婷色拍ww47| 男女爽爽无遮挡午夜视频|