2012-06-12 37 views
5

khi tôi vẽ một cái gì đó như thế (chỉ cần bản vẽ ngẫu nhiên ở đây):DrawingContext.DrawLine: Bút không có độ mờ đục đầy đủ?

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; 
    } 
} 

màu sắc của DrawLine và DrawEllipse hỗn hợp. (Tôi đã tìm ra rằng nó chỉ với DrawLine sử dụng một cây bút, và không phải với các hình thức khác như Rectangle và Ellipse, sử dụng một Brush). Lạ lùng ngay cả với màu sắc từ LinearGradientBrush của một nền tảng Grids cơ bản (argh). Tôi muốn chúng được đặt theo thứ tự z với đầy đủ độ mờ.

Đây mã 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> 

Cảm ơn sự giúp đỡ nào.

+0

Tôi đã thực hiện một giải pháp thay thế bằng cách sử dụng DrawRectangle với một bàn chải điền được vẽ bằng bút vẽ DrawLine. Tôi vẫn tự hỏi tại sao Bút không có độ mờ hoàn toàn. – Julian

+0

'Bút 'có độ mờ đục đầy đủ, nhưng trong trường hợp của bạn, các đường mỏng đến nỗi chúng bị mờ và có vẻ nửa trong suốt. Đọc câu trả lời của tôi để biết thêm thông tin và các giải pháp được đề xuất :). Vẽ hình chữ nhật cho phép bạn mô phỏng chỉ các đường ngang và dọc. Vẽ đường, nhưng với chiều rộng lớn hơn nên làm các trick;). –

Trả lời

2

Mã bạn đã đăng đang vẽ các đường kẻ mỏng cạnh nhau. Mỗi người trong số họ là antialiased và đã có mặt của nó mờ. Tôi cho rằng hiệu ứng trộn độ mờ đục Bạn mô tả xảy ra vì điều này.

Nếu bạn vẽ một đường dày (nghĩa là với chiều rộng 10), hiệu ứng sẽ không xuất hiện.

Vì vậy, giải pháp phụ thuộc vào những gì chính xác Bạn đang cố gắng để đạt được:

  • bạn có thể thử để vô hiệu hóa khử răng cưa, nếu đây là thỏa đáng, để biết thêm thông tin về vấn đề này, hãy xem ở đây: Disabling antialiasing on a WPF image
  • vẽ các đường bằng Bút có độ rộng lớn hơn, nghĩa là new Pen(Brushes.Black, 2)
  • trong trường hợp cụ thể này của các đường vẽ gần nhau, bạn có thể tăng bộ đếm 0,5f thay vì 1, vì vậy hãy thay thế for (int i = 0; i <= 100 - 1; i++) bằng for (float i = 0.0f; i <= 100 - 1; i+=0.5f).
  • nếu bạn không ngại viết thêm một số mã, bạn có thể tạo lớp Bitmap tùy chỉnh của riêng bạn mà không làm cho hình ảnh bị mờ. Một số giải pháp có sẵn ở đây http://www.nbdtech.com/Blog/archive/2008/11/20/blurred-images-in-wpf.aspx và trong trang web tham chiếu có
+0

Tôi không vẽ được đường rộng 1px, nhưng đường 2px được vẽ hoàn toàn mờ đục. Đây là một ví dụ tốt: http://daniel-albuschat.blogspot.com/2011/04/avoiding-anti-aliasing-when-drawing.html – Monsignor

4

Có hai vấn đề khử răng cưa, hoặc tiểu pixeling, với RenderTargetBitmap:

1.

Vô hiệu hóa phụ pixeling cho bitmap chính nó (ví dụ, khi nó được trả lại trong một UIElement). điều này được giải quyết bằng cách áp dụng:

RenderOptions.SetBitmapScalingMode(image1, BitmapScalingMode.NearestNeighbor); 

(trong đó image1 là đối tượng Hình ảnh WPF).

Nó chỉ được hỗ trợ cho .NET 4 trở lên. Trong trường hợp cụ thể của bạn không quan trọng vì các dòng được hiển thị pixel-sau-pixel.

2.

Tắt tính năng tạo pixel phụ khi hiển thị INTO RenderTargetBitmap. Nó có thể đạt được bằng phương thức RenderOptions.SetEdgeMode với giá trị tham số của EdgeMode.Aliased.

TUY NHIÊN, phương pháp này sẽ chỉ làm việc nếu:

  • Phương pháp này được gọi là cho một đối tượng DrawingGroup.

  • Hình học chống răng cưa chỉ được lồng trong hỗn hợp bản vẽ thông thường (ví dụ: nếu DrawingGroup chứa hình chữ nhật có VisualBrush gói gọn một DrawingVisual, nội dung của DrawingVisual đó sẽ bị khử răng cưa ngay cả khi bạn sử dụng phương pháp đó).

Vì vậy bạn có thể viết lại mã của bạn như sau:

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

Đó là ví dụ hoạt động. Cảm ơn! –

1

khác (dễ dàng hơn) cách đây:

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

Ví dụ, bạn chỉ cần có để tạo ra một lớp như:

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

và thay thế dụ DrawingVisual của bạn với AliasedDrawingVisual:

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; 
Các vấn đề liên quan