简体   繁体   English

在图形上使用graphics.ScaleTransform

[英]Use graphics.ScaleTransform on Drawing

At the moment I develope a ChartControl and it works just pretty well in my opinion, but now I'm at a point where it would be nice to have the ability to zoom the drawed signal for better analyzing. 目前,我开发了一个ChartControl,并且在我看来它可以很好地工作,但是现在我处于能够缩放绘制的信号以进行更好的分析的能力的位置。

At the moment I calculate the needed points like this: 目前,我这样计算所需的点:

for (int i = 0; i < PointsCount; i++){
    xAxisPoint = xAxisOP.X + i * (xAxisWidth / PointsCount);
    yAxisPoint = yAxisHeight * data[i].Point / Divisor;

    if(yAxisPoint > yAxisHeight){
        yAxisPoint = yAxisHeight;  
    }

    if(yAxisPoint < -yAxisHeight){
        yAxisPoint = -yAxisHeight;
    }

    Points[i] = new PointF(xAxisPoint, yAxisOP.Y + yAxisPoint);
}

if(zoom){
    graphics.ScaleTransform(0.2f*ZoomFactor, 0.2f*ZoomFactor);
}

using (Pen plotPen = new Pen(plotColor, 1)){
    graphics.DrawLines(plotPen, Points);
}

But the problem is: When it zooms in, the zoom is way too big and is drawn outside the bounds of my control. 但是问题是:放大时,缩放太大,并超出了控件的范围。

Is there a way to specify an area in which it should be Scaled (zoomed)? 有没有办法指定应该缩放(缩放)的区域?

For the final question: Is there a way to specify an area in which it should be scaled/zoomed? 对于最后一个问题: 是否有一种方法可以指定应该缩放/缩放的区域? you need a combination of SetClip , TranslateTransform and ScaleTransform . 你需要的组合SetClipTranslateTransformScaleTransform

Here is an example. 这是一个例子。

It uses a 它使用

  • target rectangle zoomTgtArea where the zoomed graphics are displayed, 显示放大的图形的目标矩形zoomTgtArea
  • a mouse location zoomOrigin where the zoom origin is, 鼠标位置zoomOrigin缩放原点所在的位置
  • a float zoomFactor , a positive float . 一个float zoomFactor ,一个正float

Initial values: 初始值:

Rectangle zoomTgtArea = new Rectangle(300, 500, 200, 200);
Point zoomOrigin = Point.Empty;   // updated in MouseMove when button is pressed
float zoomFactor = 2f;

The trick to zoom in on only a part of the graphics is to display the graphics twice , once normally and once with the transformations of the Graphics object. 仅放大一部分图形的技巧是将图形显示两次 ,一次正常显示一次,一次通过Graphics对象的转换一次显示。

Let's try: 我们试试吧:

private void pictureBox_Paint(object sender, PaintEventArgs e)
{
    // normal drawing
    DrawStuff(e.Graphics);

    // for the movable zoom we want a small correction
    Rectangle cr = pictureBox.ClientRectangle;
    float pcw =  cr.Width / (cr.Width - ZoomTgtArea.Width / 2f) ;
    float pch =  cr.Height / (cr.Height - ZoomTgtArea.Height / 2f) ;

    // now we prepare the graphics object; note: order matters!
    e.Graphics.SetClip(zoomTgtArea );
     // we can either follow the mouse or keep the output area fixed:
    if (cbx_fixed.Checked)
        e.Graphics.TranslateTransform( ZoomTgtArea.X -  zoomCenter.X * zoomFactor,
                                        ZoomTgtArea.Y -  zoomCenter.Y * zoomFactor);
    else
        e.Graphics.TranslateTransform(  - zoomCenter.X * zoomFactor * pcw,
                                        - zoomCenter.Y * zoomFactor * pch);
    // finally zoom
    e.Graphics.ScaleTransform(zoomFactor, zoomFactor);

    // and display zoomed
    DrawStuff(e.Graphics);
}

The DrawStuff I used is simple: 我使用的DrawStuff很简单:

void DrawStuff(Graphics g)
{
    bool isZoomed = g.Transform.Elements[0]!= 1   
                ||  g.Transform.OffsetX != 0 | g.Transform.OffsetY != 0;
    if (isZoomed) g.Clear(Color.Gainsboro);   // pick your back color

    // all your drawing here!
    Rectangle r =  new Rectangle(10, 10, 500, 800);  // some size
    using (Font f = new Font("Tahoma", 11f))
        g.DrawString(text, f, Brushes.DarkSlateBlue, r);
}

Its only extra is clearing the background so the normal drawing won't shine through the zoomed version.. 唯一的好处是清除背景,这样正常的图形就不会在缩放版本中发光。

Let's see: 让我们来看看:

在此处输入图片说明

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM