2012-06-12 54 views
5

當我得出類似的東西(只是隨機這裏圖紙):DrawingContext.DrawLine:筆沒有完全不透明?

public partial class MainWindow : Window 
{ 
    public MainWindow() 
    { 
     InitializeComponent(); 

     DrawingVisual visual = new DrawingVisual(); 
     DrawingContext context = visual.RenderOpen(); 

     Pen pen = new Pen(Brushes.Black, 1); 

     context.DrawEllipse(Brushes.YellowGreen, pen, new Point(0,0), 40, 40); 

     for (int i = 0; i <= 100 - 1; i++) 
      context.DrawLine(new Pen(Brushes.Black, 1), new Point(0, i), new Point(i, i)); 

     context.Close(); 

     RenderTargetBitmap bmp = new RenderTargetBitmap(100, 100, 96, 96, PixelFormats.Pbgra32); 

     bmp.Render(visual); 
     image1.Source = bmp; 
    } 
} 

的DrawLine和DrawEllipse搭配的顏色。(我發現只有使用筆的DrawLine才能使用筆,而不使用像Rectangle和Ellipse等其他形式的筆刷)。奇怪的是,即使使用來自底層網格背景(argh)的LinearGradientBrush的顏色。 我希望他們每個都是完全不透明的z-Ordered。

這裏的XAML代碼:

<Window x:Class="WpfApplication2.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     Title="MainWindow" Height="350" Width="525"> 
    <Image Name="image1" Stretch="None" /> 
</Window> 

感謝您的幫助。

+0

我通過使用DrawRectangle和填充筆在筆中插入DrawLine來制定解決方法。我仍然想知道爲什麼筆沒有完全不透明。 – Julian

+0

'筆'已經完全不透明,但在你的情況下,線條太薄,以至於模糊,似乎是半透明的。閱讀我的答案以獲取更多信息並提供解決方案:)。繪製矩形允許您僅模擬水平線和垂直線。畫線,但寬度更大應該做的伎倆;)。 –

回答

2

您發佈的代碼是繪製多條彼此相鄰的細線。它們中的每一個都是抗混淆的並且其側面模糊。我想你所描述的不透明度混合效果是因爲這個原因發生的。

如果畫了一條粗線(即寬度爲10),則不會出現效果。

因此,解決方案取決於正是你要實現的目標:

  • 你可以嘗試禁用抗鋸齒,如果這是令人滿意的,關於它的更多信息,看看這裏:Disabling antialiasing on a WPF image
  • 用筆畫出線條的寬度更大,即new Pen(Brushes.Black, 2)
  • 在這種特殊情況下畫線相互靠近時,可以將計數器增加0.5f而不是1,所以用for (float i = 0.0f; i <= 100 - 1; i+=0.5f)代替for (int i = 0; i <= 100 - 1; i++)
  • 如果您不介意編寫更多的代碼,您可以創建自己的自定義位圖類,它不會使圖像模糊。一些解決方案可以在這裏找到http://www.nbdtech.com/Blog/archive/2008/11/20/blurred-images-in-wpf.aspx,並在網站上引用的有
+0

我未能繪製1px寬度線,但2px線繪製完全不透明。這是一個很好的例子:http://daniel-albuschat.blogspot.com/2011/04/avoiding-anti-aliasing-when-drawing.html – Monsignor

4

有抗鋸齒的兩個問題,或子pixeling,與RenderTargetBitmap:

1.

禁用子pixeling爲位圖本身(例如,當它在UIElement內呈現時)。這通過應用來解決:

RenderOptions.SetBitmapScalingMode(image1, BitmapScalingMode.NearestNeighbor); 

(其中image1是WPF圖像對象)。

它僅支持.NET 4及以上版本。 在您的具體情況下,它不會影響像素線後像素。

2.

渲染INTO的RenderTargetBitmap時禁用子pixeling。它可以通過RenderOptions.SetEdgeMode方法實現,參數值爲EdgeMode.Aliased。

然而,這種方法將工作僅當:

  • 該方法被調用的DrawingGroup對象。

  • 抗鋸齒幾何僅通過常規繪製複合(例如,如果DrawingGroup包含具有VisualBrush的矩形封裝DrawingVisual,即使使用該方法,該DrawingVisual的內容也將反鋸齒)。

因此,你可以重寫代碼如下:

DrawingVisual visual = new DrawingVisual(); 
    DrawingGroup group = new DrawingGroup(); 

    Pen pen = new Pen(Brushes.Black, 1); 

    group.Children.Add(new GeometryDrawing(Brushes.YellowGreen, pen, new EllipseGeometry(new Point(0,0), 40, 40))); 

    for (int i = 0; i <= 100 - 1; i++) 
     group.Children.Add(new GeometryDrawing(null, new Pen(Brushes.Black, 1), new LineGeometry(new Point(0, i), new Point(i, i)))); 

    RenderOptions.SetEdgeMode(group, EdgeMode.Aliased); 

    DrawingContext context = visual.RenderOpen(); 
    context.DrawDrawing(group); 
    context.Close(); 

    RenderTargetBitmap bmp = new RenderTargetBitmap(100, 100, 96, 96, PixelFormats.Pbgra32); 

    bmp.Render(visual); 
    image1.Source = bmp; 
+0

這是一個工作的例子。謝謝! –

1

另一個(容易)這裏的方法:

https://stackoverflow.com/a/10257614/2463642

對於你的榜樣,你只需要創建一個類如:

public class AliasedDrawingVisual : DrawingVisual 
    { 
     public AliasedDrawingVisual() 
     { 
      this.VisualEdgeMode = EdgeMode.Aliased; 
     } 
    } 

與AliasedDrawingVisual更換您DrawingVisual實例:

DrawingVisual visual = new AliasedDrawingVisual(); // Here is the only change 
    DrawingContext context = visual.RenderOpen(); 

    Pen pen = new Pen(Brushes.Black, 1); 

    context.DrawEllipse(Brushes.YellowGreen, pen, new Point(0,0), 40, 40); 

    for (int i = 0; i <= 100 - 1; i++) 
     context.DrawLine(new Pen(Brushes.Black, 1), new Point(0, i), new Point(i, i)); 

    context.Close(); 

    RenderTargetBitmap bmp = new RenderTargetBitmap(100, 100, 96, 96, PixelFormats.Pbgra32); 

    bmp.Render(visual); 
    image1.Source = bmp;