zoukankan      html  css  js  c++  java
  • 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();

            }
        }
    }
  • 相关阅读:
    [示例] Firemonkey 面包屑导航
    [试玩] FMXLinux (Firemonkey for Linux) Linux 桌面开发(第三方插件)
    [修正] Firemonkey SpeedButton 鼠标移开按钮后 IsPressed 为 False 的问题
    [笔记] FireDAC DataSet 导入及导出 JSON
    [笔记] 升級到 Delphi 10.2 Tokyo 笔记
    [示例] 用代码设置 ListView 颜色 (只适用 Win 平台,无需修改官方源码)
    [上架] iOS 上架更新版本号建议
    [教学] Delphi IDE 文件搜寻功能
    Loadrunner相关问题
    数据导出excel数据丢失
  • 原文地址:https://www.cnblogs.com/hbb0b0/p/1929880.html
Copyright © 2011-2022 走看看