2017-01-23 4 views
0

Я пытаюсь использовать WritableBitmap, чтобы сделать некоторые манипуляции с изображениями на растровых изображениях на уровне пикселей. Но я не могу заставить его работать. Что я хочу сделать, это манипулировать пиксельными данными WritableBitmap после того, как я присвойте Image.Source свойство с моим bitmap.I googled, и единственное, что я нашел, - это вызов метода bitmap.Invalidate(), но он, кажется, устарел, поскольку я не смог найти этот метод в классе WritableBitmap.Следующий код, который я использую, чтобы получить изображение обновлено но не повезло:Обновление WritableBitmap после Image.Source было установлено

wbitmap.Lock(); 
    wbitmap.WritePixels(rect, pixels, stride, 0); 
    wbitmap.AddDirtyRect(new Int32Rect(0, 0, width, height)); 
    wbitmap.Unlock(); 

    //given that i've already assigned image.Source with "wbitmap" 
    image.InvalidateVisual(); 

любые мысли по этому вопросу?

EDIT

я был бы признателен за любые предложения для другого способа БЫСТРОГО 2D рисования в WPF лучше, WritableBitmap.

+0

Lock/AddDirtyRect/Unlock фактически не изменяет никаких данных пикселя. Вы пробовали WritePixels? Вызов InvalidateVisual в элементе управления изображением никогда не должен быть необходимым. – Clemens

+0

уверен, что я делаю, я обновил код. –

ответ

1

Следующий простой пример показывает, как непрерывно писать WriteableBitmap, когда он назначен свойству Source элемента управления изображением.

Часть XAML именно эта:

<Window ...> 
    <Grid> 
     <Image x:Name="image"/> 
    </Grid> 
</Window> 

В коде позади есть таймер, который перезаписывает WriteableBitmap десять раз в секунду со случайным значением цвета пикселя. Обратите внимание, что вы должны разрешить небезопасный код в свойствах проекта Visual Studio (на вкладке «Построение»).

В качестве альтернативы Lock/AddDirtyRect/Unlock вы также можете позвонить по телефону writePixels. Однако подход Lock также позволяет записывать другой поток не-UI в BackBuffer.

public partial class MainWindow : Window 
{ 
    private readonly WriteableBitmap bitmap 
     = new WriteableBitmap(100, 100, 96, 96, PixelFormats.Bgr32, null); 

    public MainWindow() 
    { 
     InitializeComponent(); 
     image.Source = bitmap; 

     var timer = new DispatcherTimer { Interval = TimeSpan.FromSeconds(0.1) }; 
     timer.Tick += OnTimerTick; 
     timer.Start(); 
    } 

    private unsafe void OnTimerTick(object sender, EventArgs e) 
    { 
     int pixelValue = (int)DateTime.Now.Ticks & 0xFFFFFF; 

     bitmap.Lock(); 
     var backBuffer = bitmap.BackBuffer; 

     for (int y = 0; y < bitmap.PixelHeight; y++) 
     { 
      for (int x = 0; x < bitmap.PixelWidth; x++) 
      { 
       var bufPtr = backBuffer + bitmap.BackBufferStride * y + x * 4; 
       *((int*)bufPtr) = pixelValue; 
      } 
     } 

     bitmap.AddDirtyRect(new Int32Rect(0, 0, bitmap.PixelWidth, bitmap.PixelHeight)); 
     bitmap.Unlock(); 
    } 
} 
+0

tnx для вашего ответа. другой вопрос, есть ли более быстрый способ сделать 2D-графику в WPF? –

+0

Это зависит от того, как именно вы определяете «2D-графика». Вы можете взглянуть на это: https://msdn.microsoft.com/en-us/library/ms742254(v=vs.110).aspx – Clemens

+0

Я хочу создать краску как редактор растрового изображения, маршрут которого должен быть идти с? –