2011-10-14 16 views
5

Estoy haciendo un dibujo personalizado usando el GDI +.Alternativa a Graphics.ScaleTransform

Normalmente si quiero para adaptarse a lo que estoy dibujando a la ventana, que calcula la proporción adecuada y ScaleTransform todo por esa relación:

e.Graphics.ScaleTransform(ratio, ratio); 

El problema con ScaleTransform es que las escalas de todo, incluyendo los trazos del lápiz y cepillos.

¿Hay un método sencillo para escalar todas las coordenadas de píxeles de lo que estoy dibujando? Cada línea, rectángulo o ruta es básicamente una serie de puntos. Entonces, puedo multiplicar todos esos puntos por la proporción de forma manual, pero ¿existe una alternativa fácil para hacer esto de forma más fluida?

Respuesta

1

se puede envolver el objeto gráfico GDI y almacenar el factor de escala

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 
} 
+2

Tenga en cuenta que si solo quiere evitar escalar porque quiere líneas delgadas (1 píxel), puede dibujar con un grosor de -1 para forzar una sola línea de píxeles independientemente de la escala. –

1

Creo que ScaleTransform funciona en cada valor numérico que concierne al contexto de GDI, por lo que desafortunadamente no puedes usarlo para las coordenadas. WPF tiene un GeometryTransform pero no conozco un equivalente en GDI +.

Si usted está preocupado acerca de la duplicación de código siempre se puede escribir un método de utilidad para dibujar las formas con un cierto nivel de escala aplicado a sus puntos.

También podría intentar invertir manualmente el ScaleTransform aplicando el inverso de él a cualquier objeto que no desee escalar; Sé que algunos pinceles exponen este método.

2

Trate de poner todos sus objetos en una instancia GraphicsPath primero. No tiene un método ScaleTransform pero puede transformar los objetos con GraphicsPath.Transform. Puede pasar una matriz de escala a través del Matrix.Scale.

+0

Parece que podría funcionar sin embargo un GraphicsPath no puede dibujar una imagen y las imágenes son una de las cosas principales que no quiero escalar. –

0

Afortunadamente, la pluma tiene una ScaleTransform local mediante el cual reescalado inversa se puede hacer para compensar transformar el mundial. Pluma.RestablecerTransform después de usar cada reescalado antes del siguiente, o la escala de pluma actual (independientemente del contexto de gráficos) puede reducirse a casi nada (en realidad, un píxel), disparar a la luna o apuntar a mitad de camino.