简体   繁体   English

Graphics.ScaleTransform的替代品

[英]Alternative to Graphics.ScaleTransform

I am doing custom drawing using the GDI+. 我正在使用GDI +进行自定义绘图。

Normally if I want to fit whatever I am drawing to the window, I calculate the appropriate ratio and I ScaleTransform everything by that ratio: 通常情况下,如果我想要适合我正在绘制的窗口,我会计算出适当的比例,并且我按比例调整ScaleTransform的所有内容:

e.Graphics.ScaleTransform(ratio, ratio);

The problem with ScaleTransform is that it scales everything including pen strokes and brushes. ScaleTransform的问题在于它可以缩放包括笔划和笔刷在内的所有内容。

Hoe do I scale all of the pixel coordinates of what I'm drawing? 我可以缩放我绘制的所有像素坐标吗? Every line, rectangle, or path is basically a series of points. 每个线,矩形或路径基本上都是一系列点。 So I can multiply all of those points by the ratio manually, but is there an easy alternative to do this more seamlessly? 所以我可以手动将所有这些点乘以比率,但是有一个简单的替代方案可以更加无缝地完成吗?

Try putting all your objects in a GraphicsPath instance first. 首先尝试将所有对象放在GraphicsPath实例中。 It doesn't have a ScaleTransform method but you can transform the objects with GraphicsPath.Transform . 它没有ScaleTransform方法,但您可以使用GraphicsPath.Transform转换对象。 You can pass a scaling matrix via Matrix.Scale . 您可以通过Matrix.Scale传递缩放矩阵。

I think ScaleTransform works on every numeric value that the GDI context is concerned with, so you can't just use it for coordinates, unfortunately. 我认为ScaleTransform适用于GDI上下文所关注的每个数值,所以不幸的是你不能只将它用于坐标。 WPF has a GeometryTransform but I don't know of an equivalent to it in GDI+. WPF有一个GeometryTransform但我不知道GDI +中的等价物。

If you're concerned about code duplication you could always write a utility method to draw the shapes with a certain scale level applied to their points. 如果您担心代码重复,您总是可以编写一个实用工具方法来绘制具有应用于其点的特定比例级别的形状。

You could also try manually reversing the ScaleTransform by applying the inverse of it to any objects you don't want scaled; 您还可以尝试通过将其反转应用于您不想缩放的任何对象来手动反转ScaleTransform ; I know some brushes expose this method. 我知道有些画笔暴露了这种方法。

You can wrap the GDI graphics object and store the scale factor 您可以包装GDI图形对象并存储比例因子

interface IDrawing
{
   void Scale(float sx, float sy);
   void Translate(float dx, float dy);
   void SetPen(Color col, float thickness);
   void DrawLine(Point from, Point to);
   // ... more methods
}

class GdiPlusDrawing : IDrawing
{
   private float scale;
   private Graphics graphics;
   private Pen pen;

   public GdiPlusDrawing(Graphics g)
   {
      float scale = 1.0f;
   }

   public void Scale(float s)
   {
       scale *= s;
       graphics.ScaleTransform(s,s);
   }

   public void SetPen(Color color, float thickness)
   {
       // Use scale to compensate pen thickness.
       float penThickness = thickness/scale;
       pen = new Pen(color, penThickness);   // Note, need to dispose.
   }

   // Implement rest of IDrawing
}

Fortunately, Pen has a local ScaleTransform by which inverse rescaling can be done to compensate for the global transform. 幸运的是,Pen有一个局部ScaleTransform,通过它可以进行反向重新缩放以补偿全局变换。 Pen.ResetTransform after using each rescaling before the next, or the current pen scaling (independent of graphics context) can shrink to nearly nothing (actually, one pixel), shoot to the moon, or points midway. Pen.ResetTransform在使用每次重新缩放之后,或当前的笔缩放(独立于图形上下文)可以缩小到几乎没有(实际上,一个像素),射击到月球,或点中途。

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

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