Альтернатива Graphics.ScaleTransform - PullRequest
5 голосов
/ 14 октября 2011

Я делаю заказное рисование с использованием GDI +.

Обычно, если я хочу вписать все, что я рисую, в окно, я вычисляю соответствующий коэффициент и масштабирую все, исходя из этого коэффициента:

e.Graphics.ScaleTransform(ratio, ratio);

Проблема со ScaleTransform заключается в том, что он масштабирует все, включая штрихи и кисти.

Как мне масштабировать все пиксельные координаты того, что я рисую? Каждая линия, прямоугольник или путь - это в основном последовательность точек. Так что я могу умножить все эти точки на соотношение вручную, но есть ли простая альтернатива, чтобы сделать это более плавно?

Ответы [ 4 ]

2 голосов
/ 14 октября 2011

Попробуйте сначала поместить все свои объекты в экземпляр GraphicsPath.У него нет метода ScaleTransform, но вы можете преобразовать объекты с помощью GraphicsPath.Transform.Вы можете передать матрицу масштабирования через Matrix.Scale.

1 голос
/ 16 октября 2011

Вы можете обернуть графический объект 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
}
1 голос
/ 14 октября 2011

Я думаю, ScaleTransform работает с каждым числовым значением, с которым связан контекст GDI, поэтому, к сожалению, вы не можете просто использовать его для координат. У WPF есть GeometryTransform, но я не знаю его эквивалента в GDI +.

Если вас беспокоит дублирование кода, вы всегда можете написать служебный метод для рисования фигур с определенным уровнем масштаба, примененным к их точкам.

Вы также можете попробовать вручную изменить ScaleTransform, применив инверсию к любым объектам, которые вы не хотите масштабировать; Я знаю, что некоторые кисти раскрывают этот метод.

0 голосов
/ 02 мая 2012

К счастью, Pen имеет локальное преобразование ScaleTransform, с помощью которого можно выполнить обратное масштабирование для компенсации глобального преобразования.Pen.ResetTransform после использования каждого изменения масштаба перед следующим, или текущее масштабирование пера (независимо от графического контекста) может уменьшиться почти до нуля (фактически один пиксель), выстрелить на луну или указать на полпути.

...