2011-10-14 20 views
5

我正在使用GDI +自定義繪圖。Graphics.ScaleTransform的替代

通常情況下,如果我想,以適應任何我畫到窗口,我計算出合適的比例,我ScaleTransform由比一切:

e.Graphics.ScaleTransform(ratio, ratio); 

與ScaleTransform的問題是,它擴展一切,包括筆劃和畫筆。

是否有一種簡單的方法縮放我正在繪製的所有像素座標?每條線,矩形或路徑基本上都是一系列點。所以我可以通過手動比例乘以所有這些點,但是有沒有更簡單的方法可以更加無縫地實現這一點?

回答

1

您可以包裝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 
} 
+2

請注意,如果您只想避免縮放,因爲您需要較薄的(1像素)線條,則可以使用-1的厚度進行繪製以強制單個像素線條,而不考慮比例。 –

1

我認爲ScaleTransform適用於GDI上下文所涉及的每個數值,因此不幸的是,您不能僅將它用於座標。 WPF有GeometryTransform,但我不知道它在GDI +中的等價物。

如果您擔心代碼重複,則可以隨時編寫一個實用程序方法來繪製應用於其點的特定比例級別的形狀。

您也可以嘗試手動反轉ScaleTransform,方法是將其反轉應用於任何不想縮放的對象;我知道一些畫筆揭露了這種方法。

2

嘗試先將所有對象放置在GraphicsPath實例中。它沒有ScaleTransform方法,但可以使用GraphicsPath.Transform轉換對象。您可以通過Matrix.Scale傳遞縮放矩陣。

+0

這聽起來像它可能工作,但是一個GraphicsPath不能繪製圖像和圖像是我不想縮放的主要事情之一。 –

0

幸運的是,筆有一個本地ScaleTransform通過逆縮放可以做,以抵消全球變換。 Pen.ResetTransform在下一次使用每個縮放之後,或者當前的筆縮放(獨立於圖形上下文)可以縮小到幾乎沒有(實際上是一個像素),拍攝到月球或中途點。