C#繪制含流動塊的管道

1,效果。

2,繪制技巧。

1,流動塊的實質是使用Pen的自定義DashStyle繪制的線,并使用線的偏移值呈現出流動的效果。

 Pen barPen = new Pen(BarColor, BarHeight);barPen.DashStyle = DashStyle.Custom;barPen.DashOffset = startOffset;barPen.DashPattern = new float[] { BarLength, GapLength };graphicsPath.StartFigure();g.DrawPath(barPen, graphicsPath);

2,使用GraphicsPath,繪制包含弧的多段線。

 GraphicsPath graphicsPath = new GraphicsPath();//特別需要注意角度旋轉方向,如果角度旋轉方向選錯就形成閉環
graphicsPath.AddArc(new Rectangle(this.Height / 2, this.Height / 2 * (-1) - 1, this.Height, this.Height), 180.0f, -90.0f);

3,對于扇形區域使用漸變色時需要使用PathGradientBrush畫刷而不是?LinearGradientBrush,?LinearGradientBrush畫刷無法實現從圓心到邊緣的顏色漸變。

void PaintRectangle(Graphics g, Rectangle rec, PointF[] points, LinearGradientMode linearGradientMode = LinearGradientMode.Vertical){//畫刷效果呈現線型分布,注意與PathGradientBrush的區別LinearGradientBrush brush = new LinearGradientBrush(rec, PipeEdgeColor, PipeCenterColor, linearGradientMode);brush.InterpolationColors = new ColorBlend() { Colors = new Color[] { PipeEdgeColor, PipeCenterColor, PipeEdgeColor }, Positions = new float[] { 0, 0.5f, 1 } };brush.InterpolationColors = new ColorBlend() { Colors = new Color[] { PipeEdgeColor, PipeCenterColor, PipeEdgeColor }, Positions = new float[] { 0, 0.5f, 1 } };g.FillRectangle(brush, rec);g.DrawLine(new Pen(BorderColor, BorderWidth), points[0], points[1]);g.DrawLine(new Pen(BorderColor, BorderWidth), points[2], points[3]);}

3,使用自定義的流動管道控件(FlowControl)

引用控件

屬性窗口設置自定義的相關屬性

設置后效果

4,代碼

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Drawing.Drawing2D;
namespace CustomControl
{public partial class FlowControl : UserControl{private float startOffset = 0.0f;private Timer mytimer = new Timer();Graphics g;public FlowControl(){InitializeComponent();設置控件樣式this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);this.SetStyle(ControlStyles.DoubleBuffer, true);this.SetStyle(ControlStyles.ResizeRedraw, true);this.SetStyle(ControlStyles.Selectable, true);this.SetStyle(ControlStyles.SupportsTransparentBackColor, true);this.SetStyle(ControlStyles.UserPaint, true);mytimer.Interval = 50;mytimer.Tick += Mytimer_Tick;mytimer.Start();}private void Mytimer_Tick(object sender, EventArgs e){startOffset += moveSpeed;if (Math.Abs(startOffset) > BarLength + GapLength){startOffset = 0;}this.Invalidate();}#region Filedsprivate int barHeight = 5;[Browsable(true), Category("自定義屬性"), Description("流動條寬度")]public int BarHeight{get { return barHeight; }set{this.barHeight = value;base.Invalidate();}}private Color barColor = Color.DodgerBlue;[Browsable(true), Category("自定義屬性"), Description("獲取或設置管道控件的流動塊顏色")]public Color BarColor{get{return this.barColor;}set{this.barColor = value;base.Invalidate();}}private Color borderColor = Color.DimGray;[Browsable(true), Category("自定義屬性"), Description("獲取或設置管道邊線顏色")]public Color BorderColor{get{return this.borderColor;}set{this.borderColor = value;base.Invalidate();}}private float borderWidth = 1;[Browsable(true), Category("自定義屬性"), Description("獲取或設置管道壁厚度")]public float BorderWidth{get{return this.borderWidth;}set{this.borderWidth = value;base.Invalidate();}}private Color pipeEdgeColor = Color.DimGray;[Browsable(true), Category("自定義屬性"), Description("獲取或設置管道邊緣顏色")]public Color PipeEdgeColor{get{return this.pipeEdgeColor;}set{this.pipeEdgeColor = value;base.Invalidate();}}private Color pipeCenterColor = Color.LightGray;[Browsable(true), Category("自定義屬性"), Description("獲取或設置管道控件的中心顏色")]public Color PipeCenterColor{get{return this.pipeCenterColor;}set{this.pipeCenterColor = value;base.Invalidate();}}private PipeTurnDirection pipeTurnLeft = PipeTurnDirection.None;[Browsable(true), Category("自定義屬性"), Description("左管道的轉向類型")]public PipeTurnDirection PipeTurnLeft{get{return this.pipeTurnLeft;}set{this.pipeTurnLeft = value;base.Invalidate();}}private PipeTurnDirection pipeTurnRight = PipeTurnDirection.None;[Browsable(true), Category("自定義屬性"), Description("右管道的轉向類型")]public PipeTurnDirection PipeTurnRight{get{return this.pipeTurnRight;}set{this.pipeTurnRight = value;base.Invalidate();}}private DirectionStyle pipeLineDirection = DirectionStyle.Horizontal;[Browsable(true), Category("自定義屬性"), Description("設置管道是橫向的還是縱向的")]public DirectionStyle PipeLineDirection{get{return this.pipeLineDirection;}set{this.pipeLineDirection = value;int temp;if (value == DirectionStyle.Horizontal){temp = Height;Height = Width;Width = temp;}else{temp = Width;Width = Height;Height = temp;}base.Invalidate();}}private bool isActive = false;[Browsable(true), Category("自定義屬性"), DefaultValue(false), Description("獲取或設置管道線是否激活液體顯示")]public bool IsActive{get{return this.isActive;}set{this.isActive = value;this.mytimer.Enabled = value;base.Invalidate();}}private float moveSpeed = 0.3f;[Browsable(true), Category("自定義屬性"), Description("管道線液體流動的速度,0為靜止,正數為正向流動,負數為反向流動")]public float MoveSpeed{get{return this.moveSpeed;}set{this.moveSpeed = value;base.Invalidate();}}private int barLength = 5;[Browsable(true), Category("自定義屬性"), Description("流動條長度")]public int BarLength{get{return this.barLength;}set{this.barLength = value;base.Invalidate();}}private int gapLength = 5;[Browsable(true), Category("自定義屬性"), Description("間隙長度")]public int GapLength{get{return this.gapLength;}set{this.gapLength = value;base.Invalidate();}}#endregionprotected override void OnResize(EventArgs e){if (PipeLineDirection == DirectionStyle.Horizontal){if (Width < 2 * Height){Width = 2 * Height;}}else{if (Height < 2 * Width){Height = 2 * Width;}}base.OnResize(e);}protected override void OnPaint(PaintEventArgs e){//  base.OnPaint(e);g = e.Graphics;Rectangle rec;Rectangle rec2;GraphicsPath graphicsPath = new GraphicsPath();if (PipeLineDirection == DirectionStyle.Horizontal){#region 水平switch (pipeTurnLeft){case PipeTurnDirection.Up:rec = new Rectangle(0, -Height, 2 * Height, 2 * Height);rec2 = new Rectangle(rec.X + (int)BorderWidth / 2, rec.Y, rec.Width - (int)BorderWidth, rec.Height - (int)BorderWidth / 2);PaintElliple(g, rec, rec2, 90, 90);// path.AddArc(new Rectangle( Height / 2, rec.Y /2, Height , Height), 90, 90);//特別需要注意角度旋轉方向,如果角度旋轉方向選錯就形成閉環graphicsPath.AddArc(new Rectangle(this.Height / 2, this.Height / 2 * (-1) - 1, this.Height, this.Height), 180.0f, -90.0f);break;case PipeTurnDirection.Down:rec = new Rectangle(0, 0, 2 * Height, 2 * Height);rec2 = new Rectangle(rec.X + (int)BorderWidth / 2, rec.Y + (int)BorderWidth / 2, rec.Width - (int)BorderWidth, rec.Height - (int)BorderWidth / 2);PaintElliple(g, rec, rec2, 180, 90);graphicsPath.AddArc(new Rectangle(Height / 2, Height / 2, Height, Height), 180, 90);break;case PipeTurnDirection.Left:case PipeTurnDirection.Right:case PipeTurnDirection.None:PointF[] points = new PointF[] { new PointF(Height, BorderWidth / 2), new PointF(0, BorderWidth / 2), new PointF(0, Height - BorderWidth / 2), new PointF(Height, Height - BorderWidth / 2) };PaintRectangle(g, new Rectangle(0, 0, Height, Height), points);graphicsPath.AddLine(new PointF(0, Height / 2), new PointF(Height, Height / 2));break;default:break;}switch (PipeTurnRight){case PipeTurnDirection.Up:rec = new Rectangle(Width - 2 * Height, -Height, 2 * Height, 2 * Height);rec2 = new Rectangle(rec.X + (int)BorderWidth / 2, rec.Y, rec.Width - (int)BorderWidth, rec.Height - (int)BorderWidth / 2);PaintElliple(g, rec, rec2, 0, 90);graphicsPath.AddArc(new Rectangle(rec.X + Height / 2, rec.Y / 2, Height, Height), 90, -90);break;case PipeTurnDirection.Down:rec = new Rectangle(Width - 2 * Height, 0, 2 * Height, 2 * Height);rec2 = new Rectangle(rec.X, rec.Y + (int)BorderWidth / 2, rec.Width - (int)BorderWidth / 2, rec.Height - (int)BorderWidth / 2);PaintElliple(g, rec, rec2, 270, 90);//特別需要注意角度旋轉方向,如果角度旋轉方向選錯就形成閉環graphicsPath.AddArc(new Rectangle(rec.X + Height / 2, Height / 2, Height, Height), 270, 90);break;case PipeTurnDirection.Left:case PipeTurnDirection.Right:case PipeTurnDirection.None:PointF[] points = new PointF[] { new PointF(Width - Height, BorderWidth / 2), new PointF(Width, BorderWidth / 2), new PointF(Width, Height - BorderWidth / 2), new PointF(Width - Height, Height - BorderWidth / 2) };PaintRectangle(g, new Rectangle(Width - Height, 0, Height, Height), points);graphicsPath.AddLine(Width - Height, Height / 2, Width, Height / 2);break;default:break;}if (Width > Height * 2){PointF[] points = new PointF[] { new PointF(Height, BorderWidth / 2), new PointF(Width - Height, BorderWidth / 2), new PointF(Height, Height - BorderWidth / 2), new PointF(Width - Height, Height - BorderWidth / 2) };PaintRectangle(g, new Rectangle(Height, 0, Width - 2 * Height, Height), points);//  graphicsPath.AddLine(Height, Height / 2,Width- Height , Height / 2);}#endregion}else{//垂直switch (pipeTurnLeft){case PipeTurnDirection.Left:rec = new Rectangle(-Width, 0, 2 * Width, 2 * Width);rec2 = new Rectangle(rec.X, rec.Y + (int)BorderWidth / 2, rec.Width - (int)BorderWidth / 2, rec.Height - (int)BorderWidth);PaintElliple(g, rec, rec2, 270, 90);// path.AddArc(new Rectangle( Height / 2, rec.Y /2, Height , Height), 90, 90);//特別需要注意角度旋轉方向,如果角度旋轉方向選錯就形成閉環graphicsPath.AddArc(new Rectangle(-this.Width / 2, this.Width / 2, this.Width, this.Width), 270.0f, 90.0f);break;case PipeTurnDirection.Right:rec = new Rectangle(0, 0, 2 * Width, 2 * Width);rec2 = new Rectangle(rec.X + (int)BorderWidth / 2, rec.Y + (int)BorderWidth / 2, rec.Width - (int)BorderWidth, rec.Height - (int)BorderWidth / 2);PaintElliple(g, rec, rec2, 180, 90);graphicsPath.AddArc(new Rectangle(Width / 2, Width / 2, Width, Width), 180, 90);break;case PipeTurnDirection.Up:case PipeTurnDirection.Down:case PipeTurnDirection.None:PointF[] points = new PointF[] { new PointF(BorderWidth / 2, 0), new PointF(BorderWidth / 2, Width), new PointF(Width - BorderWidth / 2, 0), new PointF(Width - BorderWidth / 2, Width) };PaintRectangle(g, new Rectangle(0, 0, Width, Width), points, LinearGradientMode.Horizontal);graphicsPath.AddLine(new PointF(Width / 2, 0), new PointF(Width / 2, Width));break;default:break;}switch (PipeTurnRight){case PipeTurnDirection.Left:rec = new Rectangle(-Width, Height - 2 * Width, 2 * Width, 2 * Width);rec2 = new Rectangle(rec.X, rec.Y + (int)BorderWidth / 2, rec.Width - (int)BorderWidth / 2, rec.Height - (int)BorderWidth);PaintElliple(g, rec, rec2, 0, 90);//特別需要注意角度旋轉方向,如果角度旋轉方向選錯就形成閉環graphicsPath.AddArc(new Rectangle(rec.X / 2, rec.Y + Width / 2, this.Width, this.Width), 0f, 90.0f);break;case PipeTurnDirection.Right:rec = new Rectangle(0, Height - 2 * Width, 2 * Width, 2 * Width);rec2 = new Rectangle(rec.X + (int)BorderWidth / 2, rec.Y + 1, rec.Width - (int)BorderWidth, rec.Height - (int)BorderWidth / 2);PaintElliple(g, rec, rec2, 90, 90);graphicsPath.AddArc(new Rectangle(Width / 2, rec.Y + Width / 2, Width, Width), 180, -90);break;case PipeTurnDirection.Up:case PipeTurnDirection.Down:case PipeTurnDirection.None:PointF[] points = new PointF[] { new PointF(BorderWidth / 2, Height - Width), new PointF(BorderWidth / 2, Height), new PointF(Width - BorderWidth / 2, Height - Width), new PointF(Width - BorderWidth / 2, Height) };PaintRectangle(g, new Rectangle(0, Height - Width, Width, Width), points, LinearGradientMode.Horizontal);graphicsPath.AddLine(new PointF(Width / 2, Height - Width), new PointF(Width / 2, Height));break;default:break;}if (Height > Width * 2){PointF[] points = new PointF[] { new PointF(BorderWidth / 2, Width), new PointF(BorderWidth / 2, Height - Width), new PointF(Width - BorderWidth / 2, Width), new PointF(Width - BorderWidth / 2, Height - Width) };PaintRectangle(g, new Rectangle(0, Width, Width, Height - 2 * Width), points, LinearGradientMode.Horizontal);// graphicsPath.AddLine(Height, Height / 2,Width- Height , Height / 2);}}if (IsActive){//繪制流動條Pen barPen = new Pen(BarColor, BarHeight);barPen.DashStyle = DashStyle.Custom;barPen.DashOffset = startOffset;barPen.DashPattern = new float[] { BarLength, GapLength };graphicsPath.StartFigure();g.DrawPath(barPen, graphicsPath);}}//繪制橢圓與圓弧void PaintElliple(Graphics g, Rectangle rec, Rectangle recArc, float startAngle, float sweepAngle){GraphicsPath graphicsPath = new GraphicsPath();graphicsPath.AddEllipse(rec);//畫刷效果呈現由中心向四方層疊     PathGradientBrush brush = new PathGradientBrush(graphicsPath);brush.CenterPoint = new PointF(rec.X + rec.Width / 2, rec.Y + rec.Height / 2);brush.InterpolationColors = new ColorBlend() { Colors = new Color[] { PipeEdgeColor, PipeCenterColor, PipeEdgeColor }, Positions = new float[] { 0, 0.5f, 1 } };g.FillPie(brush, rec, startAngle, sweepAngle);g.DrawArc(new Pen(BorderColor, BorderWidth), recArc, startAngle, sweepAngle);}void PaintRectangle(Graphics g, Rectangle rec, PointF[] points, LinearGradientMode linearGradientMode = LinearGradientMode.Vertical){//畫刷效果呈現線型分布,注意與PathGradientBrush的區別LinearGradientBrush brush = new LinearGradientBrush(rec, PipeEdgeColor, PipeCenterColor, linearGradientMode);brush.InterpolationColors = new ColorBlend() { Colors = new Color[] { PipeEdgeColor, PipeCenterColor, PipeEdgeColor }, Positions = new float[] { 0, 0.5f, 1 } };brush.InterpolationColors = new ColorBlend() { Colors = new Color[] { PipeEdgeColor, PipeCenterColor, PipeEdgeColor }, Positions = new float[] { 0, 0.5f, 1 } };g.FillRectangle(brush, rec);g.DrawLine(new Pen(BorderColor, BorderWidth), points[0], points[1]);g.DrawLine(new Pen(BorderColor, BorderWidth), points[2], points[3]);}}/// <summary>/// 管道左、右的轉向類型/// </summary>public enum PipeTurnDirection{Up = 1,Down,Left,Right,None}/// <summary>/// 管道的樣式,水平還是數值/// </summary>public enum DirectionStyle{Horizontal = 1,Vertical}
}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/45809.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/45809.shtml
英文地址,請注明出處:http://en.pswp.cn/web/45809.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

MySQL-日志-優化

目錄 介紹一下mysql 的日志 redo log 和binlog 的區別及應用場景 redo log 和 binlog 在恢復數據庫有什么區別? redo log 是怎么實現持久化的? redo log除了崩潰恢復還有什么其他作用? &#xff08;順序寫&#xff09; redo log 怎么刷入磁盤的知道嗎&#xff1f; 兩階…

重塑水利未來:智慧水利解決方案的探索與實踐,從物聯網、大數據到人工智能,科技如何賦能水利行業,實現智慧化管理與決策

本文關鍵詞&#xff1a;智慧水利、智慧水利工程、智慧水利發展前景、智慧水利技術、智慧水利信息化系統、智慧水利解決方案、數字水利和智慧水利、數字水利工程、數字水利建設、數字水利概念、人水和協、智慧水庫、智慧水庫管理平臺、智慧水庫建設方案、智慧水庫解決方案、智慧…

探索 IPython 的歷史記錄:全局命令的魔法

探索 IPython 的歷史記錄&#xff1a;全局命令的魔法 在數據科學和編程的世界里&#xff0c;IPython 以其強大的交互式特性成為了開發者和科學家們的首選工具。其中&#xff0c;IPython 的歷史記錄功能是其眾多亮點之一。本文將帶你深入探索如何在 IPython 中使用 %history 魔…

Python之爬蟲基礎

Python 是進行網絡爬蟲開發的熱門選擇&#xff0c;主要是因為其擁有豐富的庫和框架&#xff0c;如 Requests、BeautifulSoup、Scrapy 等&#xff0c;這些工具極大地簡化了網頁數據的抓取和處理過程。以下是一些 Python 爬蟲的基礎知識和步驟&#xff1a; 1. 理解網絡爬蟲 網絡…

如何通過3D開發組件HOOPS增強Navisworks數據訪問?

隨著建筑信息模型&#xff08;BIM&#xff09;和建筑、工程和施工&#xff08;AEC&#xff09;市場的快速發展&#xff0c;對Navisworks支持的需求也在不斷增長。特別是在多個公司贊助Navisworks項目的大環境下&#xff0c;HOOPS組件的支持顯得尤為重要。這些公司包括一家大型電…

【多模態學習筆記二】MINIGPT-4論文閱讀

MINIGPT-4:ENHANCING VISION-LANGUAGE UNDERSTANDING WITH ADVANCED LARGE LANGUAGE MODELS 提出的MiniGPT-4使用一個投影層,將凍結的視覺編碼器與凍結的先進的LLM Vicuna對齊。我們的工作首次揭示,將視覺特征與先進的大型語言模型正確對齊可以具有GPT-4所展示的許多先進的多…

從MySQL切換PostgreSQL后,改動的地方,注意事項!!!

1、大寫字段加上雙引號&#xff0c;寫了腳本可以參考&#xff1a;mysql轉pg腳本 2、IFNULL轉換為COALESCE。 3、LIMIT分頁兩個參數一個page&#xff0c;limit轉換為如下寫法&#xff1a; // 計算 offset&#xff0c;這里假設 page 從 1 開始int offset (page - 1) * limit;sql…

導航專業入門,高考/考研假期預習指南

導航專業入門&#xff0c;高考/考研假期預習指南 七月來臨&#xff0c;各省高考分數已揭榜完成。而高考的完結并不意味著學習的結束&#xff0c;而是新旅程的開始。對于有志于踏入IT領域的高考少年們&#xff0c;這個假期是開啟探索IT世界的絕佳時機。作為該領域的前行者和經驗…

DRF分頁器(Django Restful Framework)

資料推薦 官方文檔 https://q1mi.github.io/Django-REST-framework-documentation/api-guide/pagination_zh/ B站沒有好的教學視頻&#xff0c;不建議看&#xff0c;直接看官方文檔吧。 PageNumberPagination 此分頁樣式接受請求查詢參數中的單個數字頁碼。 Request: GET h…

【14】Github Copilot環境搭建

環境搭建 這里以Visual Studio Code為例&#xff0c;安裝好vs code&#xff0c;打開擴展側邊菜單欄&#xff0c;搜索“Github Copilot”&#xff0c;會出現如下圖的兩個插件&#xff0c;點擊安裝第一個&#xff0c;另一個會附帶一起安裝&#xff0c;然后彈出提示重新啟動vs co…

對于棧和鏈表,數組之間關系的一些探索

先貼臉來個圖 這是一個解析圖&#xff0c;總體是個棧&#xff08;stacks&#xff09;細分有數組和鏈表【注意這兒的linkedlist可不是Java集合List中的linklist】 對于棧&#xff0c;如果我們想向棧中添加元素&#xff0c;或者想從中刪除元素&#xff0c;都必須從一個地方開始&…

阿里云DSW實例中安裝并運行Neo4J

想嘗試使用大模型對接Neo4J&#xff0c;在阿里云DSW實例中安裝了Neo4J&#xff0c;卻無法通過本地瀏覽器訪問在DSW實例中運行的Neo4J。嘗試了改neo4j.conf文件&#xff0c;以及添加專用網絡的公共IP地址等方法&#xff0c;均沒有成功。最后決定直接在服務器的命令行進行各種Cyp…

uniapp 頁面字體亂碼問題解決【已解決】

這個不是我們本身代碼的問題&#xff0c;調整一下編譯器就好了 打開編譯器文件 2,然后以指定編碼重新打開&#xff0c;選擇utf-8就行了 非常簡單 &#xff0c;如果你選擇了之后重新渲染頁面還是亂碼的話&#xff0c;你就把項目關掉&#xff0c;重新啟動就OK了。。。

從零開始學習嵌入式----結構體struct和union習題回顧

一、通過結構體和自定義函數實現成績從大到小的排序&#xff0c;要求在主函數內定義結構體數組。 #include <stdio.h> //定義一個結構體類型 typedef struct Student {int age;char name[32];float score; } STU; //定義一個函數實現成績從小到大的排序 void fun(STU *p…

基于搜索二叉樹的停車收費管理系統

系統效果&#xff1a;錄入汽車信息 查看汽車信息 收費信息查看 查詢車庫車輛 代碼展示&#xff1a; //SearchBinaryTree.h #pragma once #include<iostream> #include<string> #include<time.h> #include<Windows.h> using namespace std;template<…

百分點科技入選《2024中國數據要素產業圖譜1.0版》

近日&#xff0c;數據猿與上海大數據聯盟發布了《2024中國數據要素產業圖譜1.0版》&#xff0c;百分點科技憑借領先的數據科學技術和深入的行業洞察力&#xff0c;入選數據管理/治理、數據分析與挖掘、應急管理三大領域。 在數據要素的發展關鍵期&#xff0c;數據作為生產要素持…

Hadoop中的YARN組件

文章目錄 YARN 的主要功能YARN 的架構YARN 的工作流程YARN 的優勢總結 YARN&#xff08;Yet Another Resource Negotiator&#xff09;是 Hadoop 生態系統中的一個關鍵組件&#xff0c;負責資源管理和作業調度。它是 Hadoop 2.x 及更高版本中的核心模塊&#xff0c;旨在提高集群…

【雷豐陽-谷粒商城 】【分布式高級篇-微服務架構篇】【26】【內網穿透】cpolar

持續學習&持續更新中… 守破離 【雷豐陽-谷粒商城 】【分布式高級篇-微服務架構篇】【27】【內網穿透】cpolar 內網穿透cpolar內網穿透聯調配置練習—使用公網地址訪問gulimall.com參考 內網穿透 正常的外網需要訪問我們項目的流程是&#xff1a; 買服務器并且有公網固定…

怎么壓縮視頻文件?簡單的壓縮視頻方法分享

視頻已成為我們日常生活中不可或缺的一部分。但隨著視頻質量的提高&#xff0c;文件大小也逐漸成為我們分享的阻礙。如何有效壓縮視頻文件&#xff0c;使其既能保持清晰&#xff0c;又能輕松分享&#xff1f;今天&#xff0c;給大家分享五種實用的視頻壓縮方法&#xff0c;快來…

簡談設計模式之適配器模式

適配器模式是結構型設計模式之一, 用于將一個類的接口轉換成客戶期望的另一個接口. 通過使用適配器模式, 原本由于接口不兼容而無法一起工作的類可以協同工作 適配器模式通常有兩種實現方式 類適配器模式 (Class Adapter Pattern&#xff09;: 使用繼承來實現適配器。**對象適…