MSDN.WhiteKnight - Stack Overflow answers
Ответ на "Как нарисовать эллипс по координатам на Image?"
Answer 1111537
Как можно нарисовать такой же эллипс по координатам, только не на канвасе а на Image?
Одно другому не противоречит - можно разместить на Canvas Image, а поверх него нарисовать эллипс. Но механизм для рисования на изображении в WPF тоже существует, это DrawingVisual и RenderTargetBitmap:
using System; using System.Collections.Generic; using System.Text; using System.Windows; using System.Windows.Controls; using System.Windows.Media; using System.Windows.Media.Imaging; namespace WpfTest { public partial class MainWindow : Window { public void circle(double x, double y, int width, int height, Image img) { Rect rect = new Rect(0, 0, img.ActualWidth, img.ActualHeight); DrawingVisual visual = new DrawingVisual(); if (rect.Width == 0 || rect.Height == 0) { rect.Width = img.Width; rect.Height = img.Height; } using (DrawingContext dc = visual.RenderOpen()) { dc.DrawImage(img.Source,rect); dc.DrawEllipse(null, new Pen(Brushes.Red, 6), new Point(x+width/2, y+height/2), width/2, height/2); } RenderTargetBitmap rtb = new RenderTargetBitmap( (int)rect.Width, (int)rect.Height, 96, 96, PixelFormats.Default); rtb.Render(visual); img.Source = rtb; } public MainWindow() { InitializeComponent(); img.Source = new BitmapImage(new Uri(@"C:\Test\Images\test.jpg")); } private void Button_Click(object sender, RoutedEventArgs e) { circle(10, 10, 50, 50, img); } } }
Данный код хорош работает, если изображение отображается в Image в натуральную величину. Если оно уменьшено, типично для растровой графики, будет потеря качества. Чтобы уменьшить ее, можно вот так изменить код отрисовки, добавив перемасштабирование:
public void circle(double x, double y, int width, int height, Image img) { double k = img.ActualWidth / img.Source.Width; Rect rect = new Rect(0, 0, img.Source.Width, img.Source.Height); DrawingVisual visual = new DrawingVisual(); if (rect.Width == 0 || rect.Height == 0) { rect.Width = img.Width; rect.Height = img.Height; } if (k == 0) { k = img.Width / img.Source.Width; } //пересчитаем координаты с учетом масштабного коэффициента x = x / k; y = y / k; width = (int)Math.Round((double)width / k); height = (int)Math.Round((double)height / k); using (DrawingContext dc = visual.RenderOpen()) { dc.DrawImage(img.Source,rect); dc.DrawEllipse(null, new Pen(Brushes.Red, 6/k), new Point(x+width/2, y+height/2), width/2, height/2); } RenderTargetBitmap rtb = new RenderTargetBitmap( (int)rect.Width, (int)rect.Height, 96, 96, PixelFormats.Default); rtb.Render(visual); img.Source = rtb; }
Но предпочтительнее было бы использовать способ с добавлением Image в Canvas и рисованием фигуры на Canvas поверх него. При таком способе полностью задействована векторная графика и потери качества не будет независимо от масштаба. Преобразовать итоговый результат в растровое изображение вы все равно сможете, используя RenderTargetBitmap уже на Canvas.
Content is retrieved from StackExchange API.
Auto-generated by ruso-archive tools.