Winform GDI+ 绘图

1. 常用结构

1) Point:点坐标

2) Size:大小

3) Rectangle:包括位置与大小

Rectangle.Location:位置坐标

Rectangle.Size:大小

4) Pen:画笔

红色笔:Pens.Red,黑色笔:Pens.Black

其它的一次类推。

5) Brush:画刷

红色画刷:Brushes.Red 黑色画刷:Brushes.Black

其它以此类推。

2. 坐标变换

对象

屏幕坐标转化为客户区坐标

客户区坐标转化为屏幕坐标

Point

PointToClinet(Point pt)

PointToScreen(Point pt)

Rectangle

RectangleToClient

RectangleToScreen

涉及坐标的程序必须先考虑是否需要坐标变换

坐标平移:

X目标=X现在+dx

Y目标=Y现在+dy

坐标缩放:

X目标=X现在*dx

Y目标=Y现在*dy

坐标旋转:

X目标=X现在*Cos(α)+Y现在*Sin(α)

Y目标= X现在*Sin(α)+Y现在*Cos(α)

综合后

clip_image002

引入矩阵

clip_image004

综合后的公式可以写为

clip_image006

clip_image008

clip_image010

坐标变换会因为顺序的不同而产生不同的结果,多次坐标变换的结果是多个矩阵相乘。

clip_image012

clip_image014

clip_image016

clip_image018

clip_image020

clip_image022

右下角矩阵说明

X

Y

隐含列

Sx 缩放因子

Ry旋转因子

0

Rx旋转因子

sy缩放因子

0

Dx平移因子

Dy平移因子

1

clip_image024

图-1 原始矩阵

clip_image026

图-2 x轴平移100个像素

clip_image028

图-3 y轴平移100个像素

clip_image030

图-4 x轴放大1.5倍

clip_image032

图-5 y轴放大1.5倍

clip_image034

图-6 x轴旋转0.5

clip_image036

图-7 y轴旋转0.5

3. 鼠标事件

事件名称

说明

OnMouseUp

鼠标松开

OnMouseDown

鼠标按下

OnMouseMove

鼠标移动

OnMouseEnter

鼠标进入

OnMouseLeave

鼠标离开

OnMouseHover

鼠标停留。Hover事件至多在Enter与Leave之间发生一次

OnMouseCaptureChanged

鼠标捕获变化,捕获发生一次,释放发生一次

4. 常见问题与解决方法

1) 如判断鼠标按下拖动

首先在鼠标的OnMouseMoveMove事件中添加如下判断:

if (e.Button == MouseButtons.Left)

{

//鼠标移动的过程中是否按下了左键

}

2) 如何避免鼠标按住旋转后划线后出现多条痕迹

在OnPaint事件中添加如下代码:

//划线之前先用背景色把原先的痕迹抹掉。

g.Clear(this.BackColor);

3) 鼠标的Capture事件

鼠标的捕获释放只能在一个控件中完成,前一个控件A捕获了鼠标后,不可能由下一个控件B捕获,必须是A释放了之后才能由B控件捕获。

假设在A控件上按住鼠标移动,鼠标移出A放在了B控件上。假设在B控件中的OnMouseHover中添加了代码弹出对话框,这样的对话框不会弹出,因为A捕获了鼠标,在A未释放之前,其他控件不可能激发鼠标相关的事件,除非其他控件捕获它之后,才可能激发它的事件。

附坐标变化程序代码:

代码
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Drawing.Drawing2D;

namespace GDITransformApp
{
    
    
public partial class Transform1 : Form
    {
        
public class MyMatrix
        {
            
public float X
            {
                
get;
                
set;
            }
            
public float Y
            {
                
get;
                
set;
            }

            
public MyMatrix(float x, float y)
            {
                X 
= x;
                Y 
= y;
            }

        }

        
#region Coordanate
        
//坐标轴X与控件边缘的距离
        private const int xPad = 80;

        
//坐标轴Y与控件边缘的距离
        private const int yPad = 60;

        
/// <summary>
        
/// X坐标标签间距
        
/// </summary>
        private int coordinateLablePadX = 20;
        
public int CoordinateLablePadX
        {
            
get
            {
                
return coordinateLablePadX;
            }

            
set
            {
                Invalidate();
                coordinateLablePadX 
= value;
            }
        }


        
/// <summary>
        
/// Y坐标标签间距
        
/// </summary>
        private int coordinateLablePadY = 30;
        
public int CoordinateLablePadY
        {
            
get
            {
                
return coordinateLablePadY;
            }

            
set
            {
                Invalidate();
                coordinateLablePadY 
= value;
            }
        }

        
/// <summary>
        
/// y坐标轴起点坐标
        
/// </summary>
        public Point YCoordinateStartPoint
        {
            
get
            {
                
return new Point(xPad, this.Height - yPad);

            }
        }


        
/// <summary>
        
///  y坐标轴终点坐标
        
/// </summary>
        public Point YCoordinateEndPoint
        {
            
get
            {
                
return new Point(xPad, yPad);
            }
        }


        
/// <summary>
        
///  x坐标轴起点坐标
        
/// </summary>
        public Point XCoordinateStartPoint
        {
            
get
            {
                
return YCoordinateStartPoint;
            }
        }

        
/// <summary>
        
///  x坐标轴终点坐标
        
/// </summary>
        public Point XCoordinateEndPoint
        {
            
get
            {
                Point current 
= new Point();
                current.X 
= Width - xPad;
                current.Y 
= Height - yPad;
                
return current;
            }
        }

        
private void DrawCoordinate(PaintEventArgs e)
        {


            Pen currentPen 
= new Pen(Color.Black);

            currentPen.EndCap 
= LineCap.ArrowAnchor;

            
//绘制Y轴
            e.Graphics.DrawLine(
                currentPen,
                YCoordinateStartPoint,
                YCoordinateEndPoint
                );

            
//绘制Y轴
            e.Graphics.DrawLine(
                currentPen,
                XCoordinateStartPoint,
                XCoordinateEndPoint
                );
            currentPen.Dispose();

            
//绘制X,Y 标签
            DrawCoordinateLabel(e.Graphics, YCoordinateStartPoint, YCoordinateEndPoint, XCoordinateStartPoint, XCoordinateEndPoint);
        }

        
/// <summary>
        
/// 绘制坐标标记
        
/// </summary>
        private void DrawCoordinateLabel(Graphics gp, Point startYPoint, Point endYPoint, Point startXPoint, Point endXPoint)
        {
            
//int y = YCoordinateStartPoint  .Y -  YCoordinateEndPoint.Y;

            
int currentValue = -1;
            
float labelX = 0, labelY = 0;
            
int pad = 5;

            
//绘制Y轴
            for (int current = YCoordinateStartPoint.Y; current > YCoordinateEndPoint.Y; current -= CoordinateLablePadY)
            {
                currentValue
++;

                SizeF textSize 
= gp.MeasureString(currentValue.ToString(), Font);

                labelX 
= YCoordinateStartPoint.X - xPad / 2;
                labelY 
= current - textSize.Height / 2;

                
//绘制label
                gp.DrawString(currentValue.ToString(), Font, Brushes.Black,
                    
new PointF(labelX, labelY)
                        );

                
//绘制|-
                gp.DrawLine(Pens.Black, new Point(YCoordinateStartPoint.X, current), new Point(YCoordinateStartPoint.X + pad, current));

            }

            currentValue 
= -1;
            
//绘制X轴
            for (int current = XCoordinateStartPoint.X; current < XCoordinateEndPoint.X; current += CoordinateLablePadX)
            {
                currentValue
++;

                SizeF textSize 
= gp.MeasureString(currentValue.ToString(), Font);

                labelY 
= XCoordinateStartPoint.Y + yPad / 2;
                labelX 
= current;

                
//绘制label
                gp.DrawString(currentValue.ToString(), Font, Brushes.Black,
                    
new PointF(labelX, labelY)
                        );

                
//绘制_|_
                gp.DrawLine(Pens.Black,
                    
new Point(current, XCoordinateStartPoint.Y),
                
new Point(current, XCoordinateStartPoint.Y - pad)
                );


            }




        }

#endregion

        
float angle = 0f;
        
float scaleX = 1f;
        
float scaleY = 1f;

        
float translateX = 1f;
        
float translateY = 1f;
        
public Transform1()
        {
            InitializeComponent();
        }

        Matrix matrix 
= new Matrix();

        List
<MyMatrix> myList = new List<MyMatrix>();


       

        
protected override void OnPaint(PaintEventArgs e)
        {
            
base.OnPaint(e);

            e.Graphics.Clear(
this.BackColor);

            DrawCoordinate(e);

            DrawRectangle();

        }

        
private void DrawRectangle()
        {
            
using (Graphics gh = CreateGraphics())
            {
               
                Rectangle rect 
= new Rectangle(100100200200);
                
                StringFormat sf
=new StringFormat();
                sf.Alignment
=StringAlignment.Center ;
                sf.LineAlignment
=StringAlignment .Center ;

                
//平移
                gh.TranslateTransform(translateX, translateY);
                
//旋转
                gh.RotateTransform(angle);
                
//缩放
                gh.ScaleTransform(scaleX, scaleY);

                
//设置gh的变换矩阵
                gh.Transform = matrix;
              
                gh.DrawRectangle(Pens.Red, rect);
                gh.DrawString(
"AAAAAAAAA"this.Font, Brushes.Blue, rect, sf);

                matrix 
= gh.Transform;

                myList.Add(
new MyMatrix(matrix.Elements[0], matrix.Elements[1]));
                myList.Add(
new MyMatrix(matrix.Elements[2], matrix.Elements[3]));
                myList.Add(
new MyMatrix(matrix.Elements[4], matrix.Elements[5]));

                
this.dgvMatrix.DataSource = myList;
          
                
            }

        }

        
private void button1_Click(object sender, EventArgs e)
        {
            angle 
+= 10;
            
this.Invalidate();
        }

        
private void btnScaleAdd_Click(object sender, EventArgs e)
        {
            scaleX 
+= 1;
            scaleY 
+= 1;
            
this.Invalidate();
        }

        
private void btnScaleSub_Click(object sender, EventArgs e)
        {
            scaleX 
-= 1;
            scaleY 
-= 1;
            
this.Invalidate();
        }

        
private void btnRolateSub_Click(object sender, EventArgs e)
        {
            angle 
-= 10;
            
this.Invalidate();
        }

        
private void btnBack_Click(object sender, EventArgs e)
        {
            angle 
= 0f;
            scaleX 
= 1f;
            scaleY 
= 1f;
            translateX 
= 0f;
            translateY 
= 0f;
            
this.Invalidate();
        }

        
private void btnTranslateAdd_Click(object sender, EventArgs e)
        {
            translateX 
+= 3f;
            translateY 
+= 3f;
            
this.Invalidate();
        }

        
private void btnTranslateSub_Click(object sender, EventArgs e)
        {
            translateX 
-= 5f;
            translateY 
-= 5f;
            
this.Invalidate();
        }

       

        
private void btnMatrixBack_Click(object sender, EventArgs e)
        {
            matrix 
= new Matrix
            (
              
1,0,
              
0,1,
              
0,0
            );
            
this.Invalidate();
        }

        
private void button1_Click_1(object sender, EventArgs e)
        {
            matrix 
= new Matrix(

               ((MyMatrix)
this.dgvMatrix.Rows[0].DataBoundItem).X, ((MyMatrix)this.dgvMatrix.Rows[0].DataBoundItem).Y ,
               ((MyMatrix)
this.dgvMatrix.Rows[1].DataBoundItem).X, ((MyMatrix)this.dgvMatrix.Rows[1].DataBoundItem).Y ,
               ((MyMatrix)
this.dgvMatrix.Rows[2].DataBoundItem).X, ((MyMatrix)this.dgvMatrix.Rows[2].DataBoundItem).Y 
               );
            
            
this.Invalidate();

        }
    }
}
原文地址:https://www.cnblogs.com/hbb0b0/p/1929880.html