WPF開發之ScreenCut截圖改變大小

来源:https://www.cnblogs.com/yanjinhua/archive/2022/07/28/16529277.html
-Advertisement-
Play Games

前言 接著上周寫的截圖控制項繼續更新 縮放操作。 1.WPF實現截屏「仿微信」 2.WPF 實現截屏控制項之移動(二)「仿微信」 正文 實現拉伸放大或縮小縮放操作需在矩形四個方向繪製8個Thumb,這裡有兩種方式 1)可以自行在XAML中硬編寫8個Thumb 2)使用裝飾器Adorner 本章使用了第二 ...


前言

接著上周寫的截圖控制項繼續更新 縮放操作

1.WPF實現截屏「仿微信」
2.WPF 實現截屏控制項之移動(二)「仿微信」

正文

實現拉伸放大或縮小縮放操作需在矩形四個方向繪製8Thumb,這裡有兩種方式
1)可以自行在XAML中硬編寫8Thumb
2)使用裝飾器Adorner

本章使用了第二種方式

一、首先新建個項目,然後創建個自定義控制項,命名為ScreenCutAdorner,然後讓它繼承Adorner

1.1

在裝飾器中定義
8個Thumb,對應8個方位點:

      const double THUMB_SIZE = 15;
      const double MINIMAL_SIZE = 20;
      Thumb lc, tl, tc, tr, rc, br, bc, bl;
      VisualCollection visCollec;
      public ScreenCutAdorner(UIElement adorned): base(adorned)
      {
          visCollec = new VisualCollection(this);
          visCollec.Add(lc = GetResizeThumb(Cursors.SizeWE, HorizontalAlignment.Left, VerticalAlignment.Center));
          visCollec.Add(tl = GetResizeThumb(Cursors.SizeNWSE, HorizontalAlignment.Left, VerticalAlignment.Top));
          visCollec.Add(tc = GetResizeThumb(Cursors.SizeNS, HorizontalAlignment.Center, VerticalAlignment.Top));
          visCollec.Add(tr = GetResizeThumb(Cursors.SizeNESW, HorizontalAlignment.Right, VerticalAlignment.Top));
          visCollec.Add(rc = GetResizeThumb(Cursors.SizeWE, HorizontalAlignment.Right, VerticalAlignment.Center));
          visCollec.Add(br = GetResizeThumb(Cursors.SizeNWSE, HorizontalAlignment.Right, VerticalAlignment.Bottom));
          visCollec.Add(bc = GetResizeThumb(Cursors.SizeNS, HorizontalAlignment.Center, VerticalAlignment.Bottom));
          visCollec.Add(bl = GetResizeThumb(Cursors.SizeNESW, HorizontalAlignment.Left, VerticalAlignment.Bottom));
      }

1.2

重寫 ArrangeOverride
在派生類中重寫時,為 FrameworkElement派生類定位子元素並確定大小:


  protected override Visual GetVisualChild(int index);
  protected override int VisualChildrenCount{get;}
  protected override Size ArrangeOverride(Size finalSize)
        {
            double offset = THUMB_SIZE / 2;
            Size sz = new Size(THUMB_SIZE, THUMB_SIZE);
            lc.Arrange(new Rect(new Point(-offset, AdornedElement.RenderSize.Height / 2 - offset), sz));
            tl.Arrange(new Rect(new Point(-offset, -offset), sz));
            tc.Arrange(new Rect(new Point(AdornedElement.RenderSize.Width / 2 - offset, -offset), sz));
            tr.Arrange(new Rect(new Point(AdornedElement.RenderSize.Width - offset, -offset), sz));
            rc.Arrange(new Rect(new Point(AdornedElement.RenderSize.Width - offset, AdornedElement.RenderSize.Height / 2 - offset), sz));
            br.Arrange(new Rect(new Point(AdornedElement.RenderSize.Width - offset, AdornedElement.RenderSize.Height - offset), sz));
            bc.Arrange(new Rect(new Point(AdornedElement.RenderSize.Width / 2 - offset, AdornedElement.RenderSize.Height - offset), sz));
            bl.Arrange(new Rect(new Point(-offset, AdornedElement.RenderSize.Height - offset), sz));
            return finalSize;
        }   

1.3

ScreenCutAdorner
完整代碼如下:

using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Shapes;

namespace WPFDevelopers.Controls
{
  public class ScreenCutAdorner : Adorner
  {
      const double THUMB_SIZE = 15;
      const double MINIMAL_SIZE = 20;
      Thumb lc, tl, tc, tr, rc, br, bc, bl;
      VisualCollection visCollec;
      public ScreenCutAdorner(UIElement adorned): base(adorned)
      {
          visCollec = new VisualCollection(this);
          visCollec.Add(lc = GetResizeThumb(Cursors.SizeWE, HorizontalAlignment.Left, VerticalAlignment.Center));
          visCollec.Add(tl = GetResizeThumb(Cursors.SizeNWSE, HorizontalAlignment.Left, VerticalAlignment.Top));
          visCollec.Add(tc = GetResizeThumb(Cursors.SizeNS, HorizontalAlignment.Center, VerticalAlignment.Top));
          visCollec.Add(tr = GetResizeThumb(Cursors.SizeNESW, HorizontalAlignment.Right, VerticalAlignment.Top));
          visCollec.Add(rc = GetResizeThumb(Cursors.SizeWE, HorizontalAlignment.Right, VerticalAlignment.Center));
          visCollec.Add(br = GetResizeThumb(Cursors.SizeNWSE, HorizontalAlignment.Right, VerticalAlignment.Bottom));
          visCollec.Add(bc = GetResizeThumb(Cursors.SizeNS, HorizontalAlignment.Center, VerticalAlignment.Bottom));
          visCollec.Add(bl = GetResizeThumb(Cursors.SizeNESW, HorizontalAlignment.Left, VerticalAlignment.Bottom));
      }

      protected override Size ArrangeOverride(Size finalSize)
      {
          double offset = THUMB_SIZE / 2;
          Size sz = new Size(THUMB_SIZE, THUMB_SIZE);
          lc.Arrange(new Rect(new Point(-offset, AdornedElement.RenderSize.Height / 2 - offset), sz));
          tl.Arrange(new Rect(new Point(-offset, -offset), sz));
          tc.Arrange(new Rect(new Point(AdornedElement.RenderSize.Width / 2 - offset, -offset), sz));
          tr.Arrange(new Rect(new Point(AdornedElement.RenderSize.Width - offset, -offset), sz));
          rc.Arrange(new Rect(new Point(AdornedElement.RenderSize.Width - offset, AdornedElement.RenderSize.Height / 2 - offset), sz));
          br.Arrange(new Rect(new Point(AdornedElement.RenderSize.Width - offset, AdornedElement.RenderSize.Height - offset), sz));
          bc.Arrange(new Rect(new Point(AdornedElement.RenderSize.Width / 2 - offset, AdornedElement.RenderSize.Height - offset), sz));
          bl.Arrange(new Rect(new Point(-offset, AdornedElement.RenderSize.Height - offset), sz));
          return finalSize;
      }
      void Resize(FrameworkElement ff)
      {
          if (Double.IsNaN(ff.Width))
              ff.Width = ff.RenderSize.Width;
          if (Double.IsNaN(ff.Height))
              ff.Height = ff.RenderSize.Height;
      }

      Thumb GetResizeThumb(Cursor cur, HorizontalAlignment hor, VerticalAlignment ver)
      {
          var thumb = new Thumb()
          {
              Width = THUMB_SIZE,
              Height = THUMB_SIZE,
              HorizontalAlignment = hor,
              VerticalAlignment = ver,
              Cursor = cur,
              Template = new ControlTemplate(typeof(Thumb))
              {
                  VisualTree = GetFactory(new SolidColorBrush(Colors.White))
              }
          };

          thumb.DragDelta += (s, e) =>
          {
              var element = AdornedElement as FrameworkElement;
              if (element == null)
                  return;
              Resize(element);
              switch (thumb.VerticalAlignment)
              {
                  case VerticalAlignment.Bottom:
                      if (element.Height + e.VerticalChange > MINIMAL_SIZE)
                          element.Height += e.VerticalChange;
                      break;

                  case VerticalAlignment.Top:
                      if (element.Height - e.VerticalChange > MINIMAL_SIZE)
                      {
                          element.Height -= e.VerticalChange;
                          Canvas.SetTop(element, Canvas.GetTop(element) + e.VerticalChange);
                      }
                      break;
              }
              switch (thumb.HorizontalAlignment)
              {
                  case HorizontalAlignment.Left:
                      if (element.Width - e.HorizontalChange > MINIMAL_SIZE)
                      {
                          element.Width -= e.HorizontalChange;
                          Canvas.SetLeft(element, Canvas.GetLeft(element) + e.HorizontalChange);
                      }
                      break;
                  case HorizontalAlignment.Right:
                      if (element.Width + e.HorizontalChange > MINIMAL_SIZE)
                          element.Width += e.HorizontalChange;
                      break;

              }
              e.Handled = true;

          };
          return thumb;

      }

      FrameworkElementFactory GetFactory(Brush back)
      {
          var fef = new FrameworkElementFactory(typeof(Ellipse));
          fef.SetValue(Ellipse.FillProperty, back);
          fef.SetValue(Ellipse.StrokeProperty, DrawingContextHelper.Brush);
          fef.SetValue(Ellipse.StrokeThicknessProperty, (double)2);
          return fef;
      }
      protected override Visual GetVisualChild(int index)
      {
          return visCollec[index];
      }

      protected override int VisualChildrenCount
      {
          get
          {
              return visCollec.Count;
          }
      }

  }
}

二、找到之前的自定義控制項ScreenCut修改為Border創建裝飾器層
AdornerLayer.GetAdornerLayer(_border);
接著給裝飾層添加裝飾器 adornerLayer.Add(screenCutAdorner);

2.1 ScreenCut監聽Border的大小變化修改四個矩形的大小與位置:

  private void _border_SizeChanged(object sender, SizeChangedEventArgs e)
     {
         var left = Canvas.GetLeft(_border);
         var top = Canvas.GetTop(_border);
         var beignPoint = new Point(left, top);
         var endPoint = new Point(left + _border.ActualWidth, top + _border.ActualHeight);
         rect = new Rect(beignPoint, endPoint);
         pointStart = beignPoint;
         MoveAllRectangle(endPoint);
         WrapPanelPosition();
     }

2.2 ScreenCut完整代碼如下:

using Microsoft.Win32;
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Interop;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using WPFDevelopers.Helpers;

namespace WPFDevelopers.Controls
{
    public enum ScreenCutMouseType
    {
        Default,
        DrawMouse,
        MoveMouse,

    }
    [TemplatePart(Name = CanvasTemplateName, Type = typeof(Canvas))]
    [TemplatePart(Name = RectangleLeftTemplateName, Type = typeof(Rectangle))]
    [TemplatePart(Name = RectangleTopTemplateName, Type = typeof(Rectangle))]
    [TemplatePart(Name = RectangleRightTemplateName, Type = typeof(Rectangle))]
    [TemplatePart(Name = RectangleBottomTemplateName, Type = typeof(Rectangle))]
    [TemplatePart(Name = BorderTemplateName, Type = typeof(Border))]
    [TemplatePart(Name = WrapPanelTemplateName, Type = typeof(WrapPanel))]
    [TemplatePart(Name = ButtonSaveTemplateName, Type = typeof(Button))]
    [TemplatePart(Name = ButtonCancelTemplateName, Type = typeof(Button))]
    [TemplatePart(Name = ButtonCompleteTemplateName, Type = typeof(Button))]
    public class ScreenCut : Window
    {
        private const string CanvasTemplateName = "PART_Canvas";
        private const string RectangleLeftTemplateName = "PART_RectangleLeft";
        private const string RectangleTopTemplateName = "PART_RectangleTop";
        private const string RectangleRightTemplateName = "PART_RectangleRight";
        private const string RectangleBottomTemplateName = "PART_RectangleBottom";
        private const string BorderTemplateName = "PART_Border";
        private const string WrapPanelTemplateName = "PART_WrapPanel";
        private const string ButtonSaveTemplateName = "PART_ButtonSave";
        private const string ButtonCancelTemplateName = "PART_ButtonCancel";
        private const string ButtonCompleteTemplateName = "PART_ButtonComplete";

        private Canvas _canvas;
        private Rectangle _rectangleLeft, _rectangleTop, _rectangleRight, _rectangleBottom;
        private Border _border;
        private WrapPanel _wrapPanel;
        private Button _buttonSave, _buttonCancel, _buttonComplete;
        private Rect rect;
        private Point pointStart, pointEnd;
        private bool isMouseUp = false;
        private Win32ApiHelper.DeskTopSize size;
        private ScreenCutMouseType screenCutMouseType = ScreenCutMouseType.Default;
        private AdornerLayer adornerLayer;
        private ScreenCutAdorner screenCutAdorner;

        static ScreenCut()
        {
            DefaultStyleKeyProperty.OverrideMetadata(typeof(ScreenCut), new FrameworkPropertyMetadata(typeof(ScreenCut)));
        }
        public override void OnApplyTemplate()
        {
            base.OnApplyTemplate();
            _canvas = GetTemplateChild(CanvasTemplateName) as Canvas;
            _rectangleLeft = GetTemplateChild(RectangleLeftTemplateName) as Rectangle;
            _rectangleTop = GetTemplateChild(RectangleTopTemplateName) as Rectangle;
            _rectangleRight = GetTemplateChild(RectangleRightTemplateName) as Rectangle;
            _rectangleBottom = GetTemplateChild(RectangleBottomTemplateName) as Rectangle;
            _border = GetTemplateChild(BorderTemplateName) as Border;
            _border.MouseLeftButtonDown += _border_MouseLeftButtonDown;
           
            _wrapPanel = GetTemplateChild(WrapPanelTemplateName) as WrapPanel;
            _buttonSave = GetTemplateChild(ButtonSaveTemplateName) as Button;
            if (_buttonSave != null)
                _buttonSave.Click += _buttonSave_Click;
            _buttonCancel = GetTemplateChild(ButtonCancelTemplateName) as Button;
            if (_buttonCancel != null)
                _buttonCancel.Click += _buttonCancel_Click;
            _buttonComplete = GetTemplateChild(ButtonCompleteTemplateName) as Button;
            if (_buttonComplete != null)
                _buttonComplete.Click += _buttonComplete_Click;
            _canvas.Background = new ImageBrush(Capture());
            _rectangleLeft.Width = _canvas.Width;
            _rectangleLeft.Height = _canvas.Height;
            
        }

        public ScreenCut()
        {
            Loaded += (s,e)=> 
            {
                adornerLayer = AdornerLayer.GetAdornerLayer(_border);
                screenCutAdorner = new ScreenCutAdorner(_border);
                adornerLayer.Add(screenCutAdorner);
                _border.SizeChanged += _border_SizeChanged;
            };
        }
        private void _border_SizeChanged(object sender, SizeChangedEventArgs e)
        {
            var left = Canvas.GetLeft(_border);
            var top = Canvas.GetTop(_border);
            var beignPoint = new Point(left, top);
            var endPoint = new Point(left + _border.ActualWidth, top + _border.ActualHeight);
            rect = new Rect(beignPoint, endPoint);
            pointStart = beignPoint;
            MoveAllRectangle(endPoint);
            WrapPanelPosition();
        }

        private void _border_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            if(screenCutMouseType == ScreenCutMouseType.Default)
                screenCutMouseType = ScreenCutMouseType.MoveMouse;
                
        }

        private void _buttonSave_Click(object sender, RoutedEventArgs e)
        {
            SaveFileDialog dlg = new SaveFileDialog();
            dlg.FileName = $"WPFDevelopers{DateTime.Now.ToString("yyyyMMddHHmmss")}.jpg";
            dlg.DefaultExt = ".jpg";
            dlg.Filter = "image file|*.jpg";

            if (dlg.ShowDialog() == true)
            {
                BitmapEncoder pngEncoder = new PngBitmapEncoder();
                pngEncoder.Frames.Add(BitmapFrame.Create(CutBitmap()));
                using (var fs = System.IO.File.OpenWrite(dlg.FileName))
                {
                    pngEncoder.Save(fs);
                    fs.Dispose();
                    fs.Close();
                }
            }
            Close();
        }

        private void _buttonComplete_Click(object sender, RoutedEventArgs e)
        {

            Clipboard.SetImage(CutBitmap());
            Close();
        }
        CroppedBitmap CutBitmap()
        {
            _border.Visibility = Visibility.Collapsed;
            _rectangleLeft.Visibility = Visibility.Collapsed;
            _rectangleTop.Visibility = Visibility.Collapsed;
            _rectangleRight.Visibility = Visibility.Collapsed;
            _rectangleBottom.Visibility = Visibility.Collapsed;
            var renderTargetBitmap = new RenderTargetBitmap((int)_canvas.Width,
  (int)_canvas.Height, 96d, 96d, System.Windows.Media.PixelFormats.Default);
            renderTargetBitmap.Render(_canvas);
            return new CroppedBitmap(renderTargetBitmap, new Int32Rect((int)rect.X, (int)rect.Y, (int)rect.Width, (int)rect.Height));
        }
        private void _buttonCancel_Click(object sender, RoutedEventArgs e)
        {
            Close();
        }

        protected override void OnPreviewKeyDown(KeyEventArgs e)
        {
            if (e.Key == Key.Escape)
                Close();
        }

        protected override void OnPreviewMouseLeftButtonDown(MouseButtonEventArgs e)
        {
            pointStart = e.GetPosition(_canvas);
            if (!isMouseUp)
            {
                screenCutMouseType = ScreenCutMouseType.DrawMouse;
                _wrapPanel.Visibility = Visibility.Hidden;
                pointEnd = pointStart;
                rect = new Rect(pointStart, pointEnd);
            }
        }
        protected override void OnPreviewMouseMove(MouseEventArgs e)
        {
            if (e.LeftButton == MouseButtonState.Pressed)
            {
                var current = e.GetPosition(_canvas);
                switch (screenCutMouseType)
                {
                    case ScreenCutMouseType.DrawMouse:
                        MoveAllRectangle(current);
                        break;
                  
                    case ScreenCutMouseType.MoveMouse:
                        MoveRect(current);
                        break;
                    default:
                        break;
                }

            }
        }
        void MoveRect(Point current)
        {
            if (current != pointStart)
            {
                Console.WriteLine($"current:{current}");
                Console.WriteLine($"pointStart:{pointStart}");
                var vector = Point.Subtract(current, pointStart);
                var left = Canvas.GetLeft(_border) + vector.X;
                var top = Canvas.GetTop(_border) + vector.Y;
                Console.WriteLine($"left:{left}");
                if (left <= 0)
                    left = 0;
                if (top <= 0)
                    top = 0;
                if (left + _border.Width >= _canvas.ActualWidth)
                    left = _canvas.ActualWidth - _border.ActualWidth;
                if (top + _border.Height >= _canvas.ActualHeight)
                    top = _canvas.ActualHeight - _border.ActualHeight;
                pointStart = current;

                Canvas.SetLeft(_border, left);
                Canvas.SetTop(_border, top);
                rect = new Rect(new Point(left, top), new Point(left + _border.Width, top + _border.Height));
                _rectangleLeft.Height = _canvas.ActualHeight;
                _rectangleLeft.Width = left <= 0 ? 0 : left >= _canvas.ActualWidth ? _canvas.ActualWidth : left;


                Canvas.SetLeft(_rectangleTop, _rectangleLeft.Width);
                _rectangleTop.Height = top <= 0 ? 0 : top >= _canvas.ActualHeight ? _canvas.ActualHeight : top;

                Canvas.SetLeft(_rectangleRight, left + _border.Width);
                var wRight = _canvas.ActualWidth - (_border.Width + _rectangleLeft.Width);
                _rectangleRight.Width = wRight <= 0 ? 0 : wRight;
                _rectangleRight.Height = _canvas.ActualHeight;

                Canvas.SetLeft(_rectangleBottom, _rectangleLeft.Width);
                Canvas.SetTop(_rectangleBottom, top + _border.Height);
                _rectangleBottom.Width = _border.Width;
                var hBottom = _canvas.ActualHeight - (top + _border.Height);
                _rectangleBottom.Height = hBottom <= 0 ? 0 : hBottom;
            }
        }

        protected override void OnPreviewMouseLeftButtonUp(MouseButtonEventArgs e)
        {
            WrapPanelPosition();
            isMouseUp = true;
            if (screenCutMouseType != ScreenCutMouseType.Default)
                screenCutMouseType = ScreenCutMouseType.Default;
        }
        void WrapPanelPosition()
        {
            _wrapPanel.Visibility = Visibility.Visible;
            Canvas.SetLeft(_wrapPanel, rect.X + rect.Width - _wrapPanel.ActualWidth);
            var y = Canvas.GetTop(_border) + _border.ActualHeight + _wrapPanel.ActualHeight;
            if (y > _canvas.ActualHeight)
                y = Canvas.GetTop(_border) - _wrapPanel.ActualHeight - 8;
            else
                y = Canvas.GetTop(_border) + _border.ActualHeight + 8;
            Canvas.SetTop(_wrapPanel, y);
        }
        void MoveAllRectangle(Point current)
        {
            pointEnd = current;
            rect = new Rect(pointStart, pointEnd);
            _rectangleLeft.Width = rect.X;
            _rectangleLeft.Height = _canvas.Height;

            Canvas.SetLeft(_rectangleTop, _rectangleLeft.Width);
            _rectangleTop.Width = rect.Width;
            double h = 0.0;
            if (current.Y < pointStart.Y)
                h = current.Y;
            else
                h = current.Y - rect.Height;

            _rectangleTop.Height = h;

            Canvas.SetLeft(_rectangleRight, _rectangleLeft.Width + rect.Width);
            _rectangleRight.Width = _canvas.Width - (rect.Width + _rectangleLeft.Width);
            _rectangleRight.Height = _canvas.Height;

            Canvas.SetLeft(_rectangleBottom, _rectangleLeft.Width);
            Canvas.SetTop(_rectangleBottom, rect.Height + _rectangleTop.Height);
            _rectangleBottom.Width = rect.Width;
            _rectangleBottom.Height = _canvas.Height - (rect.Height + _rectangleTop.Height);

            _border.Height = rect.Height;
            _border.Width = rect.Width;
            Canvas.SetLeft(_border, rect.X);
            Canvas.SetTop(_border, rect.Y);
            
        }
       
        BitmapSource Capture()
        {

            IntPtr hBitmap;
            IntPtr hDC = Win32ApiHelper.GetDC(Win32ApiHelper.GetDesktopWindow());
            IntPtr hMemDC = Win32ApiHelper.CreateCompatibleDC(hDC);
            size.cx = Win32ApiHelper.GetSystemMetrics(0);
            size.cy = Win32ApiHelper.GetSystemMetrics(1);
            hBitmap = Win32ApiHelper.CreateCompatibleBitmap(hDC, size.cx, size.cy);
            if (hBitmap != IntPtr.Zero)
            {
                IntPtr hOld = (IntPtr)Win32ApiHelper.SelectObject(hMemDC, hBitmap);
                Win32ApiHelper.BitBlt(hMemDC, 0, 0, size.cx, size.cy, hDC, 0, 0, Win32ApiHelper.TernaryRasterOperations.SRCCOPY);
                Win32ApiHelper.SelectObject(hMemDC, hOld);
                Win32ApiHelper.DeleteDC(hMemDC);
                Win32ApiHelper.ReleaseDC(Win32ApiHelper.GetDesktopWindow(), hDC);
                var bsource = Imaging.CreateBitmapSourceFromHBitmap(hBitmap, IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions());
                Win32ApiHelper.DeleteObject(hBitmap);
                GC.Collect();
                return bsource;
            }
            return null;
        }

    }
}
  

三、運行效果如下



您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 1. 簡介 1.1什麼是Mybatis MyBatis 是一款優秀的持久層框架 它支持自定義 SQL、存儲過程以及高級映射。 MyBatis 免除了幾乎所有的 JDBC 代碼以及設置參數和獲取結果集的工作。 MyBatis 可以通過簡單的 XML 或註解來配置和映射原始類型、介面和 Java POJ ...
  • 問題描述 用python 讀取csv文件時,報錯utf-8' codec can't decode byte 0xff in position 0: invalid start byte 問題原因 打開所用的編碼方式不對,需要指定該csv文件所用編碼 解決方法 1.找到該csv文件所用編碼方法 用記 ...
  • 兄弟們,溫故而知新,可以為師矣。 就是說,我們所學過的東西,要去多複習,這樣才能總結出屬於自己的理解,這樣就可以做老師了。 但是我以為的我以為,後面可以改成,將自己所學及所領會的教給別人,這樣才能更加記憶深刻。 今日內容:Python將多個文件多列進行關聯 知識點 文件讀寫 基礎語法 異常處理 迴圈 ...
  • 背景 過去,我們運維著“能做一切”的大型單體應用程式。這是一種將產品推向市場的很好的方式,因為剛開始我們也只需要讓我們的第一個應用上線。 而且我們總是可以回頭再來改進它的。部署一個大應用總是比構建和部署多個小塊要容易。 集中式: 集群: 分散式: 分散式和集中式會配合使用。 我們在搭建網站的時候,為 ...
  • static關鍵字 1.Java中的靜態 1.1static修飾成員變數 static修飾的成員變數屬於類、也稱為類變數,類對象可以使用。使用時可以直接用類名調用。 定義格式:`static 數據類型 變數名;` 例子: class A{ static String city="China"; } ...
  • 1.此為GitHub項目的學習記錄,記錄著我的思考,代碼基本都有註釋。 2.可以作為Python初學者鞏固基礎的絕佳練習,原題有些不妥的地方我也做了一些修正。 3.建議大家進行Python編程時使用英語,工作時基本用英語。 4.6~17題為level1難度,18-22題為level3難度,其餘都為l ...
  • [數據結構-線性表1.1] 數組(.NET源碼學習) 數組,一種數據類型(在絕大數語言中不是基本數據類型)且為引用類型,在記憶體中以連續的記憶體單元進行分配,所以其大小在創建對象後為定值,不可更改。 一.記憶體分配 對於兩種不同數據類型而言,其記憶體分配方式是不同的。值類型直接在棧(C#中稱為堆棧Stack ...
  • 一 併發編程簡介 1.1 關於併發和並行 併發和並行的概念: 併發:(Concurrent),在某個時間段內,如果有多個任務執行,即有多個線程在操作時,如果系統只有一個CPU,則不能真正同時進行一個以上的線程, 它只能把CPU運行時間劃分成若幹個時間段,再將時間段分配給各個線程執行,在一個時間段的線 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...