[收藏转载]C# GDI+ 简单绘图(一)

最近对GDI+这个东西接触的比较多,也做了些简单的实例,比如绘图板,仿QQ截图等.

  废话不多说了,我们先来认识一下这个GDI+,看看它到底长什么样.

  GDI+:Graphics Device Interface Plus也就是图形设备接口,提供了各种丰富的图形图像处理功能;在C#.NET中,使用GDI+处理二维(2D)的图形和图像,使用DirectX处理三维(3D)的图形图像,图形图像处理用到的主要命名空间是System . Drawing:提供了对GDI+基本图形功能的访问,主要有Graphics类、Bitmap类、从Brush类继承的类、Font类、Icon类、Image类、Pen类、Color类等.

  大概了解了什么是GDI+后,我们来看一下绘图要用到的主要工具,要画图,肯定要画板吧,在C#中画板可以通过Graphics这个类来创建,有了画板,总得弄个笔什么之类的吧,不然怎么画呀,难不成我们用手指画.笔又可以分好多种类,比如铅笔,画刷等.它们的区别主要是铅笔可以用来画线条,而画刷呢,嘿嘿,自己考虑下.在c#中我们可以用Pen,Brush类来实现类似功能.颜料则自然是用Color类了.

  有了工具,我们就可以开始动手了!(所需命名空间:using System.Drawing;)

  实现效果:在空白窗体中画基本图形

  准备一个画板:

  创建一个画板主要有3种方式:

  A: 在窗体或控件的Paint事件中直接引用Graphics对象

  B: 利用窗体或某个控件的CreateGraphics方法

  C: 从继承自图像的任何对象创建Graphics对象

  这次我们就先以A为例:

private void Form1_Paint(object sender, PaintEventArgs e)
    {
      Graphics g = e.Graphics; //创建画板,这里的画板是由Form提供的.
    }

  然后,我们要只笔:

private void Form1_Paint(object sender, PaintEventArgs e)
    {
      Graphics g = e.Graphics; //创建画板,这里的画板是由Form提供的.
      Pen p = new Pen(Color.Blue, 2);//定义了一个蓝色,宽度为的画笔
    }

  接下来我们就可以来画画了.

private void Form1_Paint(object sender, PaintEventArgs e)
    {
      Graphics g = e.Graphics; //创建画板,这里的画板是由Form提供的.
      Pen p = new Pen(Color.Blue, 2);//定义了一个蓝色,宽度为的画笔
      g.DrawLine(p, 10, 10, 100, 100);//在画板上画直线,起始坐标为(10,10),终点坐标为(100,100)
      g.DrawRectangle(p, 10, 10, 100, 100);//在画板上画矩形,起始坐标为(10,10),宽为,高为
      g.DrawEllipse(p, 10, 10, 100, 100);//在画板上画椭圆,起始坐标为(10,10),外接矩形的宽为,高为
    }

  效果图如下:

  c# GDI+简单绘图(一)

  在上一片里已经向大家介绍了如何使用GDI+绘制简单的图像,这一片继续向大家介绍其它一些绘图知识.

  1.首先我们来看下上一片中我们使用过的Pen.

  Pen的属性主要有: Color(颜色),DashCap(短划线终点形状),DashStyle(虚线样式),EndCap(线尾形状), StartCap(线头形状),Width(粗细)等.我们可以用Pen 来画虚线,带箭头的直线等

Pen p = new Pen(Color.Blue, 5);//设置笔的粗细为,颜色为蓝色
Graphics g = this.CreateGraphics();
//画虚线
p.DashStyle = DashStyle.Dot;//定义虚线的样式为点
g.DrawLine(p, 10, 10, 200, 10);
//自定义虚线
p.DashPattern = new float[] { 2, 1 };//设置短划线和空白部分的数组
g.DrawLine(p, 10, 20, 200, 20);
//画箭头,只对不封闭曲线有用
p.DashStyle = DashStyle.Solid;//实线
p.EndCap = LineCap.ArrowAnchor;//定义线尾的样式为箭头
g.DrawLine(p, 10, 30, 200, 30);
g.Dispose();
p.Dispose();

  以上代码运行结果:

c# GDI+简单绘图(二)

  2.接下来我们来看下Brush的使用

  作用:我们可以用画刷填充各种图形形状,如矩形、椭圆、扇形、多边形和封闭路径等,主要有几种不同类型的画刷:

  ?     SolidBrush:画刷最简单的形式,用纯色进行绘制

  ?     HatchBrush:类似于 SolidBrush,但是可以利用该类从大量预设的图案中选择绘制时要使用的图案,而不是纯色

  ?     TextureBrush:使用纹理(如图像)进行绘制

  ?     LinearGradientBrush:使用沿渐变混合的两种颜色进行绘制

  ?     PathGradientBrush :基于编程者定义的唯一路径,使用复杂的混合色渐变进行绘制

  我们这里只是简单介绍使用其中的几种:

Graphics g = this.CreateGraphics();
Rectangle rect = new Rectangle(10, 10, 50, 50);//定义矩形,参数为起点横纵坐标以及其长和宽
//单色填充
SolidBrush b1 = new SolidBrush(Color.Blue);//定义单色画刷     
g.FillRectangle(b1, rect);//填充这个矩形
//字符串
g.DrawString("字符串", new Font("宋体", 10), b1, new PointF(90, 10));
//用图片填充
TextureBrush b2 = new TextureBrush(Image.FromFile(@"e:picture1.jpg"));
rect.Location = new Point(10, 70);//更改这个矩形的起点坐标
rect.Width = 200;//更改这个矩形的宽来
rect.Height = 200;//更改这个矩形的高
g.FillRectangle(b2, rect);
//用渐变色填充
rect.Location = new Point(10, 290);
LinearGradientBrush b3 = new LinearGradientBrush(rect, Color.Yellow , Color.Black , LinearGradientMode.Horizontal);
g.FillRectangle(b3, rect);

  运行效果图:

c# GDI+简单绘图(二)

  3.坐标轴变换

  在winform中的坐标轴和我们平时接触的平面直角坐标轴不同,winform中的坐标轴方向完全相反:窗体的左上角为原点(0,0),水平向左则X增大,垂直下向则Y增大

 

c# GDI+简单绘图(二)

  接下来,我们来实际操作下,通过旋转坐标轴的方向来画出不同角度的图案,或通过更改坐标原点的位置来平衡坐标轴的位置.

Graphics g = this.CreateGraphics();
//单色填充
//SolidBrush b1 = new SolidBrush(Color.Blue);//定义单色画刷     
Pen p = new Pen(Color.Blue,1);
//转变坐标轴角度
for (int i = 0; i < 90; i++)
{
  g.RotateTransform(i);//每旋转一度就画一条线
  g.DrawLine(p, 0, 0, 100, 0);
  g.ResetTransform();//恢复坐标轴坐标
}
//平移坐标轴
g.TranslateTransform(100, 100);
g.DrawLine(p, 0, 0, 100, 0);
g.ResetTransform();
//先平移到指定坐标,然后进行度旋转
g.TranslateTransform(100,200);
for (int i = 0; i < 8; i++)
{
g.RotateTransform(45);
g.DrawLine(p, 0, 0, 100, 0);
}
g.Dispose();

  运行效果图:

c# GDI+简单绘图(二)

  4.最后我们来看下Graphics这个画板上我们还可以画什么

  其实我们上面用到的都是在画一些简单的图形,直线,矩形,扇形,圆孤等,我们还可以用它来绘制图片,这可以用它的DrawImage方法.这里我不详细讲解,大家有兴趣可以自己去MSDN了解下.我们后面会讲到的截图就会用到这个方法.

 感谢大家的支持,这几天从早忙到晚,一个字累呀!!!现在挺困的,但是又不习惯这么早睡觉,哎~~还是利用这个时间继续来写第三篇吧.

  前两篇已经基本向大家介绍了绘图的基本知识.那么,我就用我们上两篇所学的,做几个例子.

  我们先来做一个简单的----仿QQ截图关于这个的例子其实网上已经有这方面的资料了,但是为了文章的完整性,还是觉得有必要讲解.

  我们先来看一下效果:

C# GDI+ 简单绘图 (三)

  (图1)

C# GDI+ 简单绘图 (三)

  (图2)

  接下来看看这是如何做到的. 

  思路:聊天窗体上有一个截图按钮,点击按钮后,程序将整个屏幕画在一个新的全屏窗体上,然后显示这个窗体.因为是全屏的窗体,并且隐藏了菜单栏、工具栏等,所以在我们看来就好像是一个桌面的截图,然后在这个新窗体上画矩形,最后保存矩形中的内容并显示在原来的聊天窗体中.

  步骤:

  A.新建一个窗体.命名为Catch.然后设置这个窗体的FormBorderStyle为None,WindowState为Maximized.

  B.我们对代码进行编辑:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
namespace Client
{
  public partial class Catch : Form
  {
    public Catch()
    {
      InitializeComponent();
    }

  用户变量#region 用户变量

    private Point DownPoint = Point.Empty;//记录鼠标按下坐标,用来确定绘图起点
    private bool CatchFinished = false;//用来表示是否截图完成
    private bool CatchStart = false;//表示截图开始
    private Bitmap originBmp;//用来保存原始图像
    private Rectangle CatchRect;//用来保存截图的矩形
    #endregion
    //窗体初始化操作
    private void Catch_Load(object sender, EventArgs e)
    {
      this.SetStyle(ControlStyles.OptimizedDoubleBuffer | ControlStyles.AllPaintingInWmPaint | ControlStyles.UserPaint, true);
      this.UpdateStyles();
      //以上两句是为了设置控件样式为双缓冲,这可以有效减少图片闪烁的问题,关于这个大家可以自己去搜索下
      originBmp = new Bitmap(this.BackgroundImage);//BackgroundImage为全屏图片,我们另用变量来保存全屏图片
    }
    //鼠标右键点击结束截图
    private void Catch_MouseClick(object sender, MouseEventArgs e)
    {
      if (e.Button == MouseButtons.Right)
      {
        this.DialogResult = DialogResult.OK;
        this.Close();
      }
    }
    //鼠标左键按下时动作
    private void Catch_MouseDown(object sender, MouseEventArgs e)
    {
      if (e.Button == MouseButtons.Left)
      {
        if (!CatchStart)
        {//如果捕捉没有开始
          CatchStart = true;
          DownPoint = new Point(e.X, e.Y);//保存鼠标按下坐标
        }
      }
    }
    private void Catch_MouseMove(object sender, MouseEventArgs e)
    {
      if (CatchStart)
      {//如果捕捉开始
        Bitmap destBmp = (Bitmap)originBmp.Clone();//新建一个图片对象,并让它与原始图片相同
        Point newPoint = new Point(DownPoint.X, DownPoint.Y);//获取鼠标的坐标
        Graphics g = Graphics.FromImage(destBmp);//在刚才新建的图片上新建一个画板
        Pen p = new Pen(Color.Blue,1);
        int width = Math.Abs(e.X - DownPoint.X), height = Math.Abs(e.Y - DownPoint.Y);//获取矩形的长和宽
        if (e.X < DownPoint.X)
        {
          newPoint.X = e.X;
        }
        if (e.Y < DownPoint.Y)
        {
          newPoint.Y = e.Y;
        }
        CatchRect = new Rectangle(newPoint,new Size(width,height));//保存矩形
        g.DrawRectangle(p,CatchRect);//将矩形画在这个画板上
        g.Dispose();//释放目前的这个画板
        p.Dispose();
        Graphics g1 = this.CreateGraphics();//重新新建一个Graphics类
        //如果之前那个画板不释放,而直接g=this.CreateGraphics()这样的话无法释放掉第一次创建的g,因为只是把地址转到新的g了.如同string一样
        g1 = this.CreateGraphics();//在整个全屏窗体上新建画板
        g1.DrawImage(destBmp,new Point(0,0));//将刚才所画的图片画到这个窗体上
        //这个也可以属于二次缓冲技术,如果直接将矩形画在窗体上,会造成图片抖动并且会有无数个矩形.
        g1.Dispose();
        destBmp.Dispose();//要及时释放,不然内存将会被大量消耗
      }
    }
    private void Catch_MouseUp(object sender, MouseEventArgs e)
    {
      if (e.Button == MouseButtons.Left)
      {
        if (CatchStart)
        {
          CatchStart = false;
          CatchFinished = true;
        }
      }
    }
    //鼠标双击事件,如果鼠标位于矩形内,则将矩形内的图片保存到剪贴板中
    private void Catch_MouseDoubleClick(object sender, MouseEventArgs e)
    {
      if (e.Button == MouseButtons.Left&&CatchFinished)
      {
        if (CatchRect.Contains(new Point(e.X, e.Y)))
        {
          Bitmap CatchedBmp = new Bitmap(CatchRect.Width, CatchRect.Height);//新建一个于矩形等大的空白图片
          Graphics g = Graphics.FromImage(CatchedBmp);
          g.DrawImage(originBmp, new Rectangle(0, 0, CatchRect.Width, CatchRect.Height), CatchRect, GraphicsUnit.Pixel);
          //把orginBmp中的指定部分按照指定大小画在画板上
          Clipboard.SetImage(CatchedBmp);//将图片保存到剪贴板
          g.Dispose();
          CatchFinished = false;
          this.BackgroundImage = originBmp;
          CatchedBmp.Dispose();
          this.DialogResult = DialogResult.OK;
          this.Close();
        }
      }
    }
  }
}

 

 C.创建了Catch窗体后,我们在截图按钮(位于聊天窗体上)上加入以下事件:

    private void bCatch_Click(object sender, EventArgs e)
    {
      if (bCatch_HideCurrent.Checked)
      {
        this.Hide();//隐藏当前窗体
        Thread.Sleep(50);//让线程睡眠一段时间,窗体消失需要一点时间
        Catch CatchForm = new Catch();
        Bitmap CatchBmp = new Bitmap(Screen.AllScreens[0].Bounds.Width, Screen.AllScreens[0].Bounds.Height);//新建一个和屏幕大小相同的图片    
        Graphics g = Graphics.FromImage(CatchBmp);
        g.CopyFromScreen(new Point(0, 0), new Point(0, 0), new Size(Screen.AllScreens[0].Bounds.Width, Screen.AllScreens[0].Bounds.Height));//保存全屏图片
        CatchForm.BackgroundImage = CatchBmp;//将Catch窗体的背景设为全屏时的图片
        if (CatchForm.ShowDialog() == DialogResult.OK)
        {//如果Catch窗体结束,就将剪贴板中的图片放到信息发送框中
          IDataObject iData = Clipboard.GetDataObject();
          DataFormats.Format myFormat = DataFormats.GetFormat(DataFormats.Bitmap);
          if (iData.GetDataPresent(DataFormats.Bitmap))
          {
            richtextbox1.Paste(myFormat);
            Clipboard.Clear();//清除剪贴板中的对象
          }
          this.Show();//重新显示窗体
        }
      }
    }

 

  这样我们的截图功能便完成了.

  我想对于初学者来说如何消去第一次绘制的图片是个比较困难的问题.如果没有采取措施,你会发现只要你鼠标移动,就会画一个矩形,这样便会出现N多的矩形,而我们只是要最后的那一个.

  一般解决这种问题的方法有两种:

  1.就是在绘制第二个图形时,我们先用与底色相同的颜色将上次绘制的图形重新绘制一下.但这往往需要底色为纯色时使用.

  2.我们并不直接将图形画在画板上,我们用一个图片A来保存原画板上的图片.然后再新建一个与图片A相同的图片B,将我们要绘制的图形画在该图片B上,然后再将该图片B画在画板上.这样图片A并没有被改变.于是第二次画的时候我们还是同样新建一个与图片A相同的图片进行绘制.那么上一次的图形就不会被保留下来.问题也就解决了.

  下一次,向大家介绍如何做一个仿windows画板的程序.

  前几篇我已经向大家介绍了如何使用GDI+来绘图,并做了一个截图的实例,这篇我向大家介绍下如何来做一个类似windows画图的工具.

  个人认为如果想做一个功能强大的绘图工具,那么单纯掌握GDI还远远不够,我的目前也只能做一个比较简单的绘图工具了.不足之处,欢迎大家讨论!

  先来看一下最终效果吧:

c# GDI+简单绘图(四)

  主要实现功能:画直线,矩形,橡皮,圆形,切换颜色,打开图片,保存图片,清除图片,手动调节画布大小;软件刚启动时,为一张空白画布,我们可以直接在画布上绘图,也可以通过菜单中的“打开”,导入一张图片,然后我们就可以在这张图片上进行绘制。

  平台:VS2005 WINFORM

  由于代码过多,在这里只简要介绍下制作步骤,提供大家工程下载.

  1.对整个界面进行布局.

  2.实现绘图工具的功能

  3.实现颜色拾取的功能,这里我们直接拿上次写的自定义控件来用.

  4.实现菜单功能

  5.实现手动调节画布大小的功能

  6.测试

  实现绘图工具的功能

  为了让代码藕合度小点,稍许用了些设计模式,因为不是很会,所以代码还是有点乱乱的,绘图工具的这些功能块全部写在了DrawTools这个类里.那么在主窗体中,只需要调用这个类来完成绘制就行了,而不需要过多的涉及到具体的绘图代码。绘图工具这个类提供的主要工具就是:铅笔、橡皮、直线、矩形、圆形、实心矩形、实心圆形。关于这些功能块的代码,并不难,只要大家对认真看过前几篇内容,那应该都看得懂。

  这里有几点要注意:

  1.如何防止记录不必要的绘图过程中的痕迹?

  这个问题在第三篇中有提到过,大家不妨先去看看那一篇。为了让代码看起来可读性高点,我设置了两个Image变量,finishingImg用来保存绘图过程中的痕迹,orginalImg用来保存已完成的绘图过程和初始时的背景图片。

  2.这个类如何与主窗体进行通信?

  当然如果直接将这些功能块写在主窗体中自然没有这个问题。但是那样代码会显得很混杂,如果只是工具代码出现问题就需要改整个项目。我在这里通过定义方法和属性,让主窗体通过给属性赋值将画板画布以及颜色什么的信息传给这个工具类,然后通过调用相应的工具方法来使用这些工具。

  3.关键属性

  要想让这些工具能正常使用,必须传递给他以下几样东西:目标画板(也就是picturebox),绘图颜色,原始画布。

  实现菜单功能

c# GDI+简单绘图(四)

  这里就需要我们对文件的操作有一点了解,大家可以去查一下相关资料。

  难点主要就是“打开”这个菜单项的实现

  我们要实现将打开后的图片在修改后重新保存就必须让文件在打开后就能关闭,否则就会因为文件打开而无法覆盖原文件。就会导致编译时弹出“GDI  一般性错误”。所以根据网上其它朋友的做法就是先将打开的图片通过GDI+将图片画到另一个画布上,然后及时关闭打开的图片和用来绘制该图片的画板。详见http://www.wanxin.org/redirect.php?tid=3&goto=lastpost

private void openPic_Click(object sender, EventArgs e)
    {
      OpenFileDialog ofd = new OpenFileDialog();//实例化文件打开对话框
      ofd.Filter = "JPG|*.jpg|Bmp|*.bmp|所有文件|*.*";//设置对话框打开文件的括展名
      if (ofd.ShowDialog() == DialogResult.OK)
      {
        Bitmap bmpformfile = new Bitmap(ofd.FileName);//获取打开的文件
        panel2.AutoScrollPosition = new Point(0,0);//将滚动条复位
        pbImg.Size = bmpformfile.Size;//调整绘图区大小为图片大小
        reSize.Location = new Point(bmpformfile.Width, bmpformfile.Height);//reSize为我用来实现手动调节画布大小用的
        //因为我们初始时的空白画布大小有限,"打开"操作可能引起画板大小改变,所以要将画板重新传入工具类
        dt.DrawTools_Graphics = pbImg.CreateGraphics();
        Bitmap bmp = new Bitmap(pbImg.Width, pbImg.Height);
        Graphics g = Graphics.FromImage(bmp);
        g.FillRectangle(new SolidBrush(pbImg.BackColor), new Rectangle(0, 0, pbImg.Width, pbImg.Height));//不使用这句话,那么这个bmp的背景就是透明的
        g.DrawImage(bmpformfile, 0, 0,bmpformfile.Width,bmpformfile.Height);//将图片画到画板上
        g.Dispose();//释放画板所占资源
        //不直接使用pbImg.Image = Image.FormFile(ofd.FileName)是因为这样会让图片一直处于打开状态,也就无法保存修改后的图片
        bmpformfile.Dispose();//释放图片所占资源
        g = pbImg.CreateGraphics();
        g.DrawImage(bmp, 0, 0);
        g.Dispose();
        dt.OrginalImg = bmp;
        bmp.Dispose();
        sFileName = ofd.FileName;//储存打开的图片文件的详细路径,用来稍后能覆盖这个文件
        ofd.Dispose();
      }
    }

  清除图像其实就是用白色填充整个画布,其它的都比较简单,这就不具体讲了。

  实现手动调节画布大小

  网上有人说使用API,但是个人觉得还是使用其它控件帮忙比较简单,至少我们还看得懂。

  思路:放置一个picturebox1(尺寸为5*5),将它固定在主画板的右下角,然后改变鼠标进入时的Cursor为箭头形状,设置鼠标按下移动时的事件,让该picturebox1 跟随鼠标移动。当鼠标松开时,将主画板的右下角坐标调整为picturebox1的坐标。

  下面来看下代码:

  其中的reSize就是我们用来帮忙的picturebox控件 

    private bool bReSize = false;//是否改变画布大小
    private void reSize_MouseDown(object sender, MouseEventArgs e)
    {
      bReSize = true;//当鼠标按下时,说明要开始调节大小
    }
    private void reSize_MouseMove(object sender, MouseEventArgs e)
    {
      if (bReSize)
      {
        reSize.Location = new Point(reSize.Location.X + e.X, reSize.Location.Y + e.Y);
      }
    }
    private void reSize_MouseUp(object sender, MouseEventArgs e)
    {
      bReSize = false;//大小改变结束
      //调节大小可能造成画板大小超过屏幕区域,所以事先要设置autoScroll为true.
      //但是滚动条的出现反而增加了我们的难度,因为滚动条上下移动并不会自动帮我们调整图片的坐标。
      //这是因为GDI绘图的坐标系不只一个,好像有三个,没有仔细了解,一个是屏幕坐标,一个是客户区坐标,还个是文档坐标。
      //滚动条的上下移动改变的是文档的坐标,但是客户区坐标不变,而location属性就属于客户区坐标,所以我们直接计算会出现错误
      //这时我们就需要知道文档坐标与客户区坐标的偏移量,这就是AutoScrollPostion可以提供的
      pbImg.Size = new Size(reSize.Location.X - (this.panel2.AutoScrollPosition.X), reSize.Location.Y - (this.panel2.AutoScrollPosition.Y));
      dt.DrawTools_Graphics = pbImg.CreateGraphics();//因为画板的大小被改变所以必须重新赋值
      //另外画布也被改变所以也要重新赋值
      Bitmap bmp = new Bitmap(pbImg.Width, pbImg.Height);
      Graphics g = Graphics.FromImage(bmp);
      g.FillRectangle(new SolidBrush(Color.White), 0, 0, pbImg.Width, pbImg.Height);
      g.DrawImage(dt.OrginalImg, 0, 0);
      g.Dispose();
      g = pbImg.CreateGraphics();
      g.DrawImage(bmp, 0, 0);
      g.Dispose();
      dt.OrginalImg = bmp;
      bmp.Dispose();
    }

 

  效果如下图(仔细看白色区域的右下角):

c# GDI+简单绘图(四)

  此时就可以通过拖动那个小方块来调节图片大小了。

  这样,主要的问题差不多已经解决了,但还是有不足这处,欢迎大家提出宝贵的意见。

转载于:https://www.cnblogs.com/zhili/archive/2013/05/24/3096101.html

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

mybaties总结+hibernate总结

一、对原生态jdbc程序中问题总结 1.1 jdbc程序 需求&#xff1a;使用jdbc查询mysql数据库中用户表的记录 statement:向数据库中发送一个sql语句 预编译statement&#xff1a;好处&#xff1a;提高数据库性能。 预编译statement向数据库中发送一个sql语句&#xff0c;数据库编译…

Python14 函数

函数 面向对象编程&#xff1a; 类----class 面向过程编程&#xff1a;过程---def 函数式编程&#xff1a;函数---def def test(x):描述x 1return x#def是定义函数的关键字#test是函数名称#&#xff08;x&#xff09;是参数#x1是 函数体&#xff0c;是一段逻辑代码#return 定义…

pandas之数值计算与统计

数值计算与统计 对于DataFrame来说&#xff0c;求和、最大、最小、平均等统计方法&#xff0c;默认是按列进行统计&#xff0c;即axis 0&#xff0c;如果添加参数axis 1则会按照行进行统计。 如果存在空值&#xff0c;在统计时默认会忽略空值&#xff0c;如果添加参数skipna …

python自动化数据报告_如何:使用Python将实时数据自动化到您的网站

python自动化数据报告This tutorial will be helpful for people who have a website that hosts live data on a cloud service but are unsure how to completely automate the updating of the live data so the website becomes hassle free. For example: I host a websit…

android intent参数是上次的结果,【Android】7.0 Intent向下一个活动传递数据、返回数据给上一个活动...

1.0 可以利用Intent吧数据传递给上一个活动&#xff0c;新建一个叫“hellotest01”的项目。新建活动FirstActivity&#xff0c;勾选“Generate Layout File”和“Launcher Activity”。image修改AndroidMainifest.xml中的内容&#xff1a;android:name".FirstActivity&quo…

学习深度学习需要哪些知识_您想了解的有关深度学习的所有知识

学习深度学习需要哪些知识有关深层学习的FAU讲义 (FAU LECTURE NOTES ON DEEP LEARNING) Corona was a huge challenge for many of us and affected our lives in a variety of ways. I have been teaching a class on Deep Learning at Friedrich-Alexander-University Erlan…

html5--3.16 button元素

html5--3.16 button元素 学习要点 掌握button元素的使用button元素 用来建立一个按钮从功能上来说&#xff0c;与input元素建立的按钮相同button元素是双标签&#xff0c;其内部可以配置图片与文字&#xff0c;进行更复杂的样式设计不仅可以在表单中使用&#xff0c;还可以在其…

如何注册鸿蒙id,鸿蒙系统真机调试证书 和 设备ID获取

鸿蒙系统真机调试创建项目创建项目创建应用创建鸿蒙应用(注意&#xff0c;测试阶段需要发邮件申请即可)关联应用项目进入关联 添加引用准备调试使用的 p12 和证书请求 csr使用以下命令// 别名"test"可以修改&#xff0c;但必须前后一致&#xff0c;密码请自行修改key…

读zepto核心源码学习JS笔记(3)--zepto.init()

上篇已经讲解了zepto.init()的几种情况,这篇就继续记录这几种情况下的具体分析. 1. 首先是第一种情况,selector为空 既然是反向分析,那我们先看看这句话的代码; if (!selector) return zepto.Z() 这里的返回值为zepto.Z();那我们继续往上找zepto.Z()函数 zepto.Z function(dom…

置信区间估计 预测区间估计_估计,预测和预测

置信区间估计 预测区间估计Estimation implies finding the optimal parameter using historical data whereas prediction uses the data to compute the random value of the unseen data.估计意味着使用历史数据找到最佳参数&#xff0c;而预测则使用该数据来计算未见数据的…

鸿蒙系统还会推出吗,华为明年所有自研设备都升级鸿蒙系统,还会推出基于鸿蒙系统的新机...

不负期许&#xff0c;华为鸿蒙OS手机版如期而至。今日(12月15日)&#xff0c;鸿蒙OS 2.0手机开发者Beta版本正式上线&#xff0c;支持运行安卓应用&#xff0c;P40、Mate 30系列可申请公测。国内媒体报道称&#xff0c;华为消费者业务软件部副总裁杨海松表示&#xff0c;按照目…

C#中将DLL文件打包到EXE文件

1&#xff1a;在工程目录增加dll目录&#xff0c;然后将dll文件复制到此目录&#xff0c;例如&#xff1a; 2&#xff1a;增加引用&#xff0c;定位到工程的dll目录&#xff0c;选中要增加的dll文件 3&#xff1a;修改dll文件夹下面的dll文件属性 选中嵌入式资源&#xff0c;不…

Oracle VM Virtual Box的安装

安装Oracle VM Virtual Box安装扩展插件 选择"管理""全局设定" 在设置对话框中&#xff0c;选择"扩展" 选择"添加包" 找到"Oracle_VM_VirtualBox_Extension_Pack-4.1.18-78361"&#xff0c;点击"打开" 5&#x…

python 移动平均线_Python中的SMA(短期移动平均线)

python 移动平均线With the evolution of technology rapidly evolving, so do strategies in the stock market. In this post, I’ll go over how I created a SMA(Short Moving Average) strategy.随着技术的飞速发展&#xff0c;股票市场的策略也在不断发展。 在本文中&…

angular中的href=unsafe:我该怎么摆脱你的溺爱!!

解决方法&#xff1a;angular.module加入下面这行&#xff1a;&#xff08;依据Angular changes urls to “unsafe:” in extension page&#xff09; .config(function($compileProvider){//注:有些版本的angularjs为$compileProvider.urlSanitizationWhitelist(/^\s*(https?…

android view gesturedetector,如何在Android中利用 GestureDetector进行手势检测

如何在Android中利用 GestureDetector进行手势检测发布时间&#xff1a;2020-11-26 16:15:21来源&#xff1a;亿速云阅读&#xff1a;92作者&#xff1a;Leah今天就跟大家聊聊有关如何在Android中利用 GestureDetector进行手势检测&#xff0c;可能很多人都不太了解&#xff0c…

Java系列笔记(4) - JVM监控与调优【转】

Java系列笔记(4) - JVM监控与调优【转】 目录 参数设置收集器搭配启动内存分配监控工具和方法调优方法调优实例 光说不练假把式&#xff0c;学习Java GC机制的目的是为了实用&#xff0c;也就是为了在JVM出现问题时分析原因并解决之。通过学习&#xff0c;我觉得JVM监控与调…

地图 c-suite_C-Suite的模型

地图 c-suiteWe’ve all seen a great picture capture an audience of stakeholders.我们所有人都看到了吸引利益相关者听众的美好画面。 Let’s just all notice that the lady in the front right is not captivated by the image on the board (Photo by Christina wocin…

动态链接库.so和静态链接库.a的区别

静态链接库&#xff1a; •扩展名&#xff1a;.a  •编译行为&#xff1a;在编译的时候&#xff0c;将函数库直接整合到执行程序中&#xff08;所以利用静态库编译生成的文档会更大&#xff09; •独立执行的状态&#xff1a;编译成功的可执行文件可以独立运行&#xff0c;不…

华为鸿蒙系统封闭,谷歌正式“除名”华为!“亲儿子”荣耀表示:暂不考虑,鸿蒙OS处境尴尬...

我们都知道&#xff0c;目前智能手机最常用操作系统就是IOS和安卓&#xff0c;占据手机系统超过99%的市场份额。由于IOS系统的封闭性&#xff0c;国内手机厂商基本上都是使用谷歌的开源安卓系统。当然华为也不例外&#xff0c;一直使用的都是安卓系统。可以说&#xff0c;安卓系…