【学习笔记】Windows GDI绘图(十一)Graphics详解(下)

文章目录

  • Graphics的方法
    • Graphics.FromImage
    • SetClip设置裁切区域
    • IntersectClip更新为相交裁切区域
    • TranslateClip平移裁切区域
    • IsVisible判断点或矩形是否在裁切区域内
    • MeasureCharacterRanges测量字符区域
    • MeasureString测量文本大小
    • MultiplyTransform矩阵变换

Graphics的方法

Graphics.FromImage

原型:

public static System.Drawing.Graphics FromImage (System.Drawing.Image image);

作用:从图像创建Graphics对象,后续可以在该对象上绘制图形等内容。

using (var image = Image.FromFile("AIWoman.png"))
{
    using (var newGraphics = Graphics.FromImage(image))
    {
        newGraphics.FillEllipse(Brushes.LightGreen, new Rectangle(50, 50, 200, 200));
        e.Graphics.DrawImage(image, 50, 50, 600, 600);
    }
}

1、从图像文件创建Image对象
2、从Image对象创建Graphics对象
3、在Graphics对象上绘制圆形
4、将上面的内容绘制到当前Graphics上。
FromImage
注意,不能从如下索引色图像创建Graphics对象:Format1bppIndexed、Format4bppIndexed、Format8bppIndexed,对索引色图像可使用Image.Save保存为其他格式。也不能从以下图像格式创建Graphics对象:Undefined、DontCare、Format16bppArgb1555和Format16bppGrayScale。
切记,在使用FromImage创建的Graphics对象后,要调用Dispose()方法。

SetClip设置裁切区域

原型:

public void SetClip (System.Drawing.Region region, System.Drawing.Drawing2D.CombineMode combineMode);
public void SetClip (System.Drawing.RectangleF rect, System.Drawing.Drawing2D.CombineMode combineMode);
public void SetClip (System.Drawing.Rectangle rect, System.Drawing.Drawing2D.CombineMode combineMode);
public void SetClip (System.Drawing.Graphics g, System.Drawing.Drawing2D.CombineMode combineMode);
public void SetClip (System.Drawing.RectangleF rect);
public void SetClip (System.Drawing.Rectangle rect);
public void SetClip (System.Drawing.Graphics g);
public void SetClip (System.Drawing.Drawing2D.GraphicsPath path);
public void SetClip (System.Drawing.Drawing2D.GraphicsPath path, System.Drawing.Drawing2D.CombineMode combineMode);

CombineMode枚举

说明
Complement现有区域被排除在新区域之外
Exclude新区域被排除在现有区域之外
Intersect两个区域的相交部分
Replace新区域替换现有区域
Union两个区域的合集
Xor取只属性某一区域的合并部分
var values = Enum.GetValues(typeof(CombineMode)) as CombineMode[];
CombineModeIndex= (CombineModeIndex+1) % values.Length;

//原裁切区域
var originRect = new Rectangle(100, 100, 200, 100);
//另一裁切区域
var newRect = new Rectangle(250, 150, 200, 100);
e.Graphics.SetClip(originRect);

Region clipRegion = new Region(newRect);
e.Graphics.SetClip(clipRegion, values[CombineModeIndex]);

//查看组合后的裁切区域(亮绿色部分)
e.Graphics.FillRectangle(Brushes.LightGreen,e.Graphics.VisibleClipBounds);

// 重置裁切区域
e.Graphics.ResetClip();

// 区域两个区域的矩形
e.Graphics.DrawRectangle(new Pen(Color.Black), originRect);
e.Graphics.DrawRectangle(new Pen(Color.Red), newRect);
e.Graphics.DrawString($"CombineMode:{values[CombineModeIndex]},亮绿区域:SetClip组合的效果", 
    Font, Brushes.Red, new PointF(20, 20));

e.Graphics.DrawString($"黑色框:原裁切区域", Font, Brushes.Black, originRect.X, originRect.Y - 20);
e.Graphics.DrawString($"红色框:另一裁切区域", Font, Brushes.Red, newRect.X, newRect.Bottom + 10);

1、获取CombineMode的各枚举值
2、定义两个矩形,一个设为当前裁切区域,另一个为组合区域,测试不同CombineMode的值的效果
3、在重置裁切区域,将两个区域的矩形绘制显示,方便观察效果。
SetClip组合

IntersectClip更新为相交裁切区域

原型:

public void IntersectClip (System.Drawing.Rectangle rect);
public void IntersectClip (System.Drawing.RectangleF rect);
public void IntersectClip (System.Drawing.Region region);

作用:将当前裁切区域更新为与指定区域的交集。

TranslateClip平移裁切区域

原型:

public void TranslateClip (int dx, int dy);
public void TranslateClip (float dx, float dy);

作用:平移裁切区域

//原裁切区域
var originRect = new Rectangle(100, 100, 200, 100);
//另一裁切区域
var newRect = new Rectangle(250, 150, 200, 100);
e.Graphics.SetClip(originRect);

Region clipRegion = new Region(newRect);
e.Graphics.IntersectClip(clipRegion);

//查看组合后的裁切区域(亮绿色部分)
e.Graphics.FillRectangle(Brushes.LightGreen, e.Graphics.VisibleClipBounds);
//平移裁切区域亮蓝部分)
e.Graphics.TranslateClip(50, 50);
e.Graphics.FillRectangle(Brushes.LightBlue, e.Graphics.VisibleClipBounds);
// 重置裁切区域
e.Graphics.ResetClip();

// 区域两个区域的矩形
e.Graphics.DrawRectangle(new Pen(Color.Black), originRect);
e.Graphics.DrawRectangle(new Pen(Color.Red), newRect);

e.Graphics.DrawString($"IntersectClip方法,与SetClip的Intersect相同,亮绿部分", Font, Brushes.Red, new PointF(20, 20));
e.Graphics.DrawString($"平移后裁切区域,亮蓝部分", Font, Brushes.Red, new PointF(20, 35));
e.Graphics.DrawString($"黑色框:原裁切区域", Font, Brushes.Black, originRect.X, originRect.Y - 20);
e.Graphics.DrawString($"红色框:另一裁切区域", Font, Brushes.Red, newRect.X, newRect.Bottom + 10);

IntersectClip等同于SetClip方法的参数为CombineMode.Intersect时的效果。

IntersectClip与TranslateClip

IsVisible判断点或矩形是否在裁切区域内

原型:

public bool IsVisible (System.Drawing.Point point);
public bool IsVisible (System.Drawing.PointF point);
public bool IsVisible (System.Drawing.Rectangle rect);
public bool IsVisible (System.Drawing.RectangleF rect);
public bool IsVisible (int x, int y);
public bool IsVisible (float x, float y);
public bool IsVisible (int x, int y, int width, int height);
public bool IsVisible (float x, float y, float width, float height);

作用:判断一个点或一个矩形是否在裁切区域内(相交也算在区域内)

[System.ComponentModel.Description("Graphics的IsVisible方法")]
public void Demo11_04(PaintEventArgs e)
{
    //原裁切区域
    var clipRect = new Rectangle(100, 100, 200, 200);
    e.Graphics.SetClip(clipRect);

    e.Graphics.FillRectangle(Brushes.LightGreen, e.Graphics.VisibleClipBounds);
    //注意,这里的宽、高要减1
    e.Graphics.DrawRectangle(Pens.Red, clipRect.X, clipRect.Y, clipRect.Width - 1, clipRect.Height - 1);

    //区域外
    var ptA = new Point(80, 80);
    var isPtAVisiable = e.Graphics.IsVisible(ptA);
    //区域内
    var ptB = new Point(120, 120);
    var isPtBVisiable = e.Graphics.IsVisible(ptB);
    //边上,也算区域内
    var ptC = new Point(100, 100);
    var isPtCVisiable = e.Graphics.IsVisible(ptC);

    //另一边要减1,所以这里不算
    var ptD = new Point(clipRect.X + clipRect.Width, clipRect.Y + clipRect.Height);
    var isPtDVisiable = e.Graphics.IsVisible(ptD);


    var rectA = new Rectangle(320, 80, 50, 50);

    var isRectAVisiable = e.Graphics.IsVisible(rectA);

    var rectB = new Rectangle(180, 180, 50, 50);

    var isRectBVisiable = e.Graphics.IsVisible(rectB);

    var rectC = new Rectangle(280, 280, 50, 50);

    var isRectCVisiable = e.Graphics.IsVisible(rectC);


    var clipBounds = e.Graphics.ClipBounds;
    e.Graphics.ResetClip();
    DrawPointIsVisiable(e, ptA, isPtAVisiable);
    DrawPointIsVisiable(e, ptB, isPtBVisiable);
    DrawPointIsVisiable(e, ptC, isPtCVisiable);
    DrawPointIsVisiable(e, ptD, isPtDVisiable);

    DrawRectIsVisiable(e, rectA, isRectAVisiable);
    DrawRectIsVisiable(e, rectB, isRectBVisiable);
    DrawRectIsVisiable(e, rectC, isRectCVisiable);

    e.Graphics.DrawString($"有效裁切区域:({clipBounds.X},{clipBounds.Y},{clipBounds.Width},{clipBounds.Height})", 
        Font, Brushes.Red, new Point(20, 20));           
}

//显示点是否可见
private void DrawPointIsVisiable(PaintEventArgs e, Point pt, bool isVisable)
{
    e.Graphics.FillEllipse(Brushes.Red, pt.X - 3, pt.Y - 3, 6, 6);
    e.Graphics.DrawString($"Pt({pt.X},{pt.Y}),是否可见:{isVisable}", Font, Brushes.Red, pt.X + 10, pt.Y);
}

//显示矩形是否可见
private void DrawRectIsVisiable(PaintEventArgs e,Rectangle rect,bool isVisable)
{
    e.Graphics.DrawRectangle(Pens.Blue, rect);
    e.Graphics.DrawString($"Rect({rect.X},{rect.Y},{rect.Width},{rect.Height}),是否可见:{isVisable}", 
        Font, Brushes.Blue, rect.Right + 10, rect.Y);
}

1、分别测试点在区域外、区域边缘、区域内的情况
2、分别测试矩形在区域外、区域相交、区域内的情况
IsVisable

MeasureCharacterRanges测量字符区域

原型:

public System.Drawing.Region[] MeasureCharacterRanges (string text, System.Drawing.Font font, System.Drawing.RectangleF layoutRect, System.Drawing.StringFormat stringFormat);

作用:给定一个文字绘制布局(需够长足以绘制文字),测量相应的文字的绘制范围。

// 设置一段文字
string measureString = "Hello,这是一段测试范围的文字";
using (Font stringFont = new Font("宋体", 16.0F))
{
    // 设置"Hello","测试范围"的字符范围
    CharacterRange[] characterRanges = { new CharacterRange(0, 5), new CharacterRange(10, 4) };

    // Create rectangle for layout.
    float x = 50.0F;
    float y = 50.0F;
    float width = 75.0F;
    float height = 500.0F;
    //注意,这个范围要能完整含文字在
    RectangleF layoutRect = new RectangleF(x, y, width, height);
    e.Graphics.DrawRectangle(Pens.LightGreen, Rectangle.Round(layoutRect));

    // 设置文字格式
    StringFormat stringFormat = new StringFormat();
    stringFormat.FormatFlags = StringFormatFlags.DirectionVertical;
    stringFormat.SetMeasurableCharacterRanges(characterRanges);

    // 绘制文字
    e.Graphics.DrawString(measureString, stringFont, Brushes.Black, x, y, stringFormat);

    // 绘制两个文字的区域
    Region[] stringRegions = e.Graphics.MeasureCharacterRanges(measureString,stringFont, layoutRect, stringFormat);

    // 绘制第一个文字区域
    RectangleF measureRect1 = stringRegions[0].GetBounds(e.Graphics);
    e.Graphics.DrawRectangle(new Pen(Color.Red, 1), Rectangle.Round(measureRect1));

    // 绘制第二个文字区域
    RectangleF measureRect2 = stringRegions[1].GetBounds(e.Graphics);
    e.Graphics.DrawRectangle(new Pen(Color.Blue, 1), Rectangle.Round(measureRect2));
}  

1、定义一段要测量的文字“Hello,这是一段测试范围的文字”,其中要测试"Hello"与"测试范围"两个字符串区域
2、定义文字绘制矩形布局
3、绘制文字
4、测量文字的范围
5、将测量范围用两个矩形框绘制到文字处。
MeasureCharacterRanges

MeasureString测量文本大小

原型:

public System.Drawing.SizeF MeasureString (string text, System.Drawing.Font font);
public System.Drawing.SizeF MeasureString (string text, System.Drawing.Font font, System.Drawing.SizeF layoutArea);
public System.Drawing.SizeF MeasureString (string text, System.Drawing.Font font, int width);
public System.Drawing.SizeF MeasureString (string text, System.Drawing.Font font, System.Drawing.PointF origin, System.Drawing.StringFormat stringFormat);
public System.Drawing.SizeF MeasureString (string text, System.Drawing.Font font, System.Drawing.SizeF layoutArea, System.Drawing.StringFormat stringFormat);
public System.Drawing.SizeF MeasureString (string text, System.Drawing.Font font, int width, System.Drawing.StringFormat format);
public System.Drawing.SizeF MeasureString (string text, System.Drawing.Font font, System.Drawing.SizeF layoutArea, System.Drawing.StringFormat stringFormat, out int charactersFitted, out int linesFilled);

作用:测量文本的范围,或限制宽度时,可自动计算行换后的高度,也统计字符个数,行数。

//设置文本和字体‌
string measureString = "待测试的文字还包含English";
Font stringFont = new Font("宋体", 16);

//测量文本大小
var stringSize = e.Graphics.MeasureString(measureString, stringFont);
var insertPt = new PointF(20, 20);
//绘制文本大小的矩形
e.Graphics.DrawRectangle(new Pen(Color.Red, 1), insertPt.X, insertPt.Y, stringSize.Width, stringSize.Height);
//绘制文本
e.Graphics.DrawString(measureString, stringFont, Brushes.Black, insertPt);


e.Graphics.TranslateTransform(100, 100);
// Set point for upper-left corner of string.
float x = 50.0F;
float y = 50.0F;
PointF ulCorner = new PointF(x, y);

// Set string format.
StringFormat newStringFormat = new StringFormat();
newStringFormat.FormatFlags = StringFormatFlags.DirectionVertical;

// Measure string.
stringSize = e.Graphics.MeasureString(measureString, stringFont, ulCorner, newStringFormat);

// Draw rectangle representing size of string.
e.Graphics.DrawRectangle(new Pen(Color.Red, 1), x, y, stringSize.Width, stringSize.Height);

// Draw string to screen.
e.Graphics.DrawString(measureString, stringFont, Brushes.Black, ulCorner, newStringFormat);

e.Graphics.TranslateTransform(100, 0);

// Set maximum layout size.
var layoutSize = new SizeF(100.0F, 300.0F);

// Set string format.
newStringFormat.FormatFlags = StringFormatFlags.DirectionVertical;

// Measure string.
stringSize = e.Graphics.MeasureString(measureString, stringFont, layoutSize, newStringFormat);

// Draw rectangle representing size of string.
e.Graphics.DrawRectangle(new Pen(Color.Red, 1), 0.0F, 0.0F, stringSize.Width, stringSize.Height);

// Draw string to screen.
e.Graphics.DrawString(measureString, stringFont, Brushes.Black, new PointF(0, 0), newStringFormat);


e.Graphics.TranslateTransform(100, 0);

// Set maximum width of string.
int stringWidth = 100;

// Set string format.
newStringFormat.FormatFlags = StringFormatFlags.DirectionVertical;

// Measure string.
stringSize = e.Graphics.MeasureString(measureString, stringFont, stringWidth, newStringFormat);

// Draw rectangle representing size of string.
e.Graphics.DrawRectangle(new Pen(Color.Red, 1), 0.0F, 0.0F, stringSize.Width, stringSize.Height);

// Draw string to screen.
e.Graphics.DrawString(measureString, stringFont, Brushes.Black, new PointF(0, 0), newStringFormat);


//============
e.Graphics.TranslateTransform(100, 0);
// Set maximum layout size.
layoutSize = new SizeF(100.0F, 300.0F);

// Set string format.
newStringFormat.FormatFlags = StringFormatFlags.DirectionVertical;

// Measure string.
int charactersFitted;
int linesFilled;
stringSize = e.Graphics.MeasureString(measureString, stringFont, layoutSize, newStringFormat, out charactersFitted, out linesFilled);

// Draw rectangle representing size of string.
e.Graphics.DrawRectangle(new Pen(Color.Red, 1), 0.0F, 0.0F, stringSize.Width, stringSize.Height);

// Draw string to screen.
e.Graphics.DrawString(measureString, stringFont, Brushes.Black, new PointF(0, 0), newStringFormat);

// Draw output parameters to screen.
string outString = "chars " + charactersFitted + ", lines " + linesFilled;
e.Graphics.DrawString(outString, stringFont, Brushes.Black, new PointF(100, 0));

测试不同参数下测量文本区域的结果。
MeasureString

MultiplyTransform矩阵变换

原型:

public void MultiplyTransform (System.Drawing.Drawing2D.Matrix matrix);//默认是MatrixOrder.Prepend
public void MultiplyTransform (System.Drawing.Drawing2D.Matrix matrix, System.Drawing.Drawing2D.MatrixOrder order);

作用:将世界变换矩阵与该矩形相乘。

var rect = new Rectangle(0, 0, 200, 100);
var pt1 = new Point(0, 0);
var pt2 = new Point(200, 100);
// Create transform matrix.
using (Matrix transformMatrix = new Matrix())
{
    //平移(200,100)
    transformMatrix.Translate(200.0F, 100.0F);
    //世界坐标顺时旋转30度
    e.Graphics.RotateTransform(30.0F);
    e.Graphics.DrawLine(Pens.Red, pt1, pt2);
    e.Graphics.DrawEllipse(new Pen(Color.Blue, 3), rect);
    //先平移,再旋转
    e.Graphics.MultiplyTransform(transformMatrix);//默认是 MatrixOrder.Prepend在
    e.Graphics.DrawLine(Pens.Blue, pt1, pt2);
    // Draw rotated, translated ellipse.
    e.Graphics.DrawEllipse(new Pen(Color.Blue, 3), rect);

    e.Graphics.ResetTransform();
    //世界坐标顺时旋转30度
    e.Graphics.RotateTransform(30.0F);
    
    //先旋转,再平移
    e.Graphics.MultiplyTransform(transformMatrix, MatrixOrder.Append);
    e.Graphics.DrawLine(Pens.Red, pt1, pt2);
    e.Graphics.DrawEllipse(new Pen(Color.Red, 3), rect);
}

分别测试应用矩阵顺序不同,导致的结果不同。
MultiplyTransform

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/679385.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

大模型时代的具身智能系列专题(九)

NYU Lerrel Pinto团队 Lerrel Pinto是NYU Courant的计算机科学助理教授,也是用机器人和人工智能实验室(CILVR小组)的一员。在加州大学伯克利分校读博士后,在CMU机器人研究所读博士,在印度理工学院古瓦哈蒂读本科。研究目标是让机器人在我们生…

JDBC学习笔记(二)进阶篇

一、JDBC 扩展 1.1 实体类和ROM 实体类代码: package com.atguigu.advanced.pojo;//类名就是数据库表的 t_ 后面的单词全写 public class Employee {private Integer empId;//emp_idprivate String empName;//emp_nameprivate Double empSalary;//emp_salarypriva…

二叉树遍历 和 线索二叉树

文章目录 1.1 二叉树遍历1.1 前提问题1: 什么叫二叉树的遍历?二叉树的三种遍历:三个概念:遍历 和 访问 和 经过重要概念:遍历过程中的经过节点,不代表访问节点 问题2:遍历和访问的联系&#xff…

利用conda进行R的安装

1.miniconda3的安装 官网:Miniconda — Conda documentation 找到对应系统、Python版本下载 wget https://mirrors.ustc.edu.cn/anaconda/miniconda/Miniconda3-latest-Linux-x86_64.sh #wget -c https://repo.continuum.io/miniconda/Miniconda3-latest-Linux-x…

Python项目代码太多if-else? 这样优化才优雅!

前言 代码中不可避免地会出现复杂的if-else条件逻辑,而简化这些条件表达式是一种提高代码可读性极为实用的技巧。 在 Python 中,有多种方法可以避免复杂的 if-else 条件逻辑,使代码更加清晰和易于维护。 筑基期 提前 return,去掉多余的 else 在 Python 中,使用"提…

C++基础编程100题-003 OpenJudge-1.1-05 输出保留12位小数的浮点数

更多资源请关注纽扣编程微信公众号 http://noi.openjudge.cn/ch0101/05/ 描述 读入一个双精度浮点数,保留12位小数,输出这个浮点数。 输入 只有一行,一个双精度浮点数。 输出 也只有一行,保留12位小数的浮点数。 样例输入…

Day 42 LVS四层负载均衡

一:负载均衡简介 1.集群是什么 ​ 集群(cluster)技术是一种较新的技术,通过集群技术,可以在付出较低成本的情况下获得在性能、可靠性、灵活性方面的相对较高的收益,其任务调度则是集群系统中的核心技术 …

LangChain学习之 Question And Answer的操作

1. 学习背景 在LangChain for LLM应用程序开发中课程中,学习了LangChain框架扩展应用程序开发中语言模型的用例和功能的基本技能,遂做整理为后面的应用做准备。视频地址:基于LangChain的大语言模型应用开发构建和评估。 2. Q&A的作用 …

web刷题记录(2)

[鹤城杯 2021]EasyP 就是php的代码审计 从中可以看出来,就是对四个if语句的绕过,然后过滤了一些语句 代码分析: 通过include utils.php;导入了一个叫做"utils.php"的文件,这意味着在该文件中可能定义了一些与本代码相…

通信协议:常见的芯片间通信协议

相关阅读 通信协议https://blog.csdn.net/weixin_45791458/category_12452508.html?spm1001.2014.3001.5482 本文将简单介绍一些常见的芯片间通信协议,但不会涉及到协议的具体细节。首先说明,芯片间通信方式根据通信时钟的区别可以分为:异步…

计算机网络ppt和课后题总结(上)

试在下列条件下比较电路交换和分组交换。要传送的报文共 x(bit)。从源点到终点共经过 k 段链路,每段链路的传播时延为 d(s),数据率为 b(b/s)。在电路交换时电路的建立时间为 s(s)。在分组交换时分组长度为 p(bit),且各结点的排队等待时间可忽…

基于YOLOv7的口罩检测

目录 1. 作者介绍2. YOLOv7网络模型2.1 算法简介2.2 数据集介绍2.3 YOLO格式数据集制作 3. 代码实现3.1 分割数据集3.2 修改数据配置文件3.3 修改训练代码,进行训练3.4 修改测试代码,进行测试3.5 检测结果 1. 作者介绍 曹宇欢,女&#xff0c…

跨越国界, 纷享销客助力企业全球业务增长

出海,已不再是企业的“备胎”,而是必须面对的“大考”!在这个全球化的大潮中,有的企业乘风破浪,勇攀高峰,也有的企业在异国他乡遭遇了“水土不服”。 面对“要么出海,要么出局”的抉择&#xff…

盲盒风尚:拆盒吧引领新潮消费趋势

在当下这个快速变化的消费时代,拆盒吧以其独特的盲盒经济模式,成为了新潮文化消费的引领者。不同于传统的购物方式,拆盒吧通过创新的玩法和多元化的产品线,为消费者带来了前所未有的购物体验。 一、拆盒吧:解锁盲盒新玩…

现代密码学-国密算法

商用密码算法种类 商用密码算法 密码学概念、协议与算法之间的依赖关系 数字签名、证书-公钥密码、散列类算法 消息验证码-对称密码 ,散列类 安全目标与算法之间的关系 机密性--对称密码、公钥密码 完整性--散列类算法 可用性--散列类、公钥密码 真实性--公…

数据结构之初始泛型

找往期文章包括但不限于本期文章中不懂的知识点: 个人主页:我要学编程(ಥ_ಥ)-CSDN博客 所属专栏:数据结构(Java版) 目录 深入了解包装类 包装类的由来 装箱与拆箱 面试题 泛型 泛型的语法与使用…

可长期操作的赚钱项目,时间自由,但不适合大学生

如何评价现在的csgo市场? 可长期操作的赚钱项目,时间自由,但不适合大学生。 都在问,有哪些可以长期做下去的赚钱项目,童话就不拐弯抹角了,csgo/steam游戏搬砖一定是最适合长期做下去的赚钱项目。 不说别人…

CondaSSLError: OpenSSL appears to be unavailable on this machine.

conda create -n x1 python3.7报错 PS C:\Users\Richardo.M.Song\Desktop\lele_seg\x1> conda create -n x1 python3.7 Collecting package metadata (current_repodata.json): failed CondaSSLError: OpenSSL appears to be unavailable on this machine. OpenSSL is requ…

Varnish讲解文章、缓存代理配置、核心功能、优势、Varnish在什么情况下会选择缓存哪些类型的内容、Varnish如何实现负载均衡功能?

varnish官网链接 Varnish文章概览 Varnish是一款高性能的HTTP加速器(web应用加速器),是一款开源软件,它能够显著提高网站的响应速度和减少服务器的负载。Varnish的设计理念是利用缓存技术,将频繁访问的静态内容存储在…

【Python】 探索Pytz库中的时区列表

基本原理 在Python中,处理时区是一个常见但复杂的问题。pytz是一个Python库,它提供了对时区的精确和丰富的支持。pytz库是datetime模块的补充,它允许更准确地处理时区信息。pytz库包括了IANA时区数据库,这个数据库包含了全球的时…