在绘图上使用 graphics.ScaleTransform
Use graphics.ScaleTransform on Drawing
目前我开发了一个 ChartControl,在我看来它工作得很好,
但现在我正处于能够缩放绘制的信号以便更好地分析的地步。
目前我这样计算所需的点数:
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);
}
但问题是:当它放大时,缩放太大,超出了我的控制范围。
有没有办法指定应该缩放(缩放)的区域?
最后一个问题:有没有办法指定一个区域应该是scaled/zoomed?你需要SetClip
, TranslateTransform
and ScaleTransform
的组合。
这是一个例子。
它使用
- 显示缩放图形的目标矩形
zoomTgtArea
,
- 缩放原点所在的鼠标位置
zoomOrigin
,
- 一个浮点数
zoomFactor
,一个正数float
。
初始值:
Rectangle zoomTgtArea = new Rectangle(300, 500, 200, 200);
Point zoomOrigin = Point.Empty; // updated in MouseMove when button is pressed
float zoomFactor = 2f;
仅放大部分图形的技巧是显示图形 两次 ,一次正常显示,一次显示 Graphics
对象的变换。
让我们试试:
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);
}
我用的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);
}
它唯一的额外功能是清除背景,这样普通绘图就不会在缩放版本中发光..
让我们看看:
目前我开发了一个 ChartControl,在我看来它工作得很好, 但现在我正处于能够缩放绘制的信号以便更好地分析的地步。
目前我这样计算所需的点数:
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);
}
但问题是:当它放大时,缩放太大,超出了我的控制范围。
有没有办法指定应该缩放(缩放)的区域?
最后一个问题:有没有办法指定一个区域应该是scaled/zoomed?你需要SetClip
, TranslateTransform
and ScaleTransform
的组合。
这是一个例子。
它使用
- 显示缩放图形的目标矩形
zoomTgtArea
, - 缩放原点所在的鼠标位置
zoomOrigin
, - 一个浮点数
zoomFactor
,一个正数float
。
初始值:
Rectangle zoomTgtArea = new Rectangle(300, 500, 200, 200);
Point zoomOrigin = Point.Empty; // updated in MouseMove when button is pressed
float zoomFactor = 2f;
仅放大部分图形的技巧是显示图形 两次 ,一次正常显示,一次显示 Graphics
对象的变换。
让我们试试:
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);
}
我用的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);
}
它唯一的额外功能是清除背景,这样普通绘图就不会在缩放版本中发光..
让我们看看: