1 回答

TA貢獻1886條經驗 獲得超2個贊
您可以使用WriteableBitmap. 這非???,但它通過將單個字節寫入位圖來工作,因此如果您需要將效果應用于繪圖,那么您必須自己編寫它們。這是一個如何使用WriteableBitmap. 在調試模式下,在我的計算機上的 1600 x 1200 像素圖像上繪制 1000 條線(每條線由 1600 個點組成)需要大約 100 毫秒,但我確信這可以優化。
我只是隨機繪制線條,但您可以從Canvas觸控筆獲取事件并捕獲其位置,并在每次筆畫后傳遞它們。
public partial class MainWindow : Window
{
private WriteableBitmap _bitmap;
private readonly Random _random = new Random();
private readonly Stopwatch _stopwatch = new Stopwatch();
private const int White = 0x00000000;
private const int Red = 0x00FF0000;
private int _width;
private int _height;
public MainWindow()
{
InitializeComponent();
CanvasImage.Loaded += OnLoaded;
}
private async void OnLoaded(object sender, RoutedEventArgs e)
{
_width = (int)DrawableCanvas.ActualWidth;
_height = (int)DrawableCanvas.ActualHeight;
_bitmap = new WriteableBitmap(_width, _height, 96, 96, PixelFormats.Bgr32, null);
CanvasImage.Source = _bitmap;
while (true)
{
unsafe
{
for (var index = 0; index < _width * _height; index++)
*((int*)_bitmap.BackBuffer + index) = White;
}
_stopwatch.Start();
for (var index = 0; index < 1000; index++)
{
var start = _random.Next(0, _width);
var points = Enumerable.Range(0, _width).Select(x => new Point((x + start) % _width, x % _height));
UpdateImage(points);
}
Debug.WriteLine($"Last 1000 draws took: {_stopwatch.ElapsedMilliseconds} ms");
_stopwatch.Reset();
await Task.Delay(300);
}
}
private void UpdateImage(IEnumerable<Point> points)
{
_bitmap.Lock();
foreach (var point in points)
{
var x = (int)point.X;
var y = (int)point.Y;
var offset = _width * y + x;
unsafe
{
*((int*)_bitmap.BackBuffer + offset) = Red;
}
}
_bitmap.AddDirtyRect(new Int32Rect(0, 0, _width, _height));
_bitmap.Unlock();
}
}
并查看:
<Grid>
<Border Width="1604" Height="1204" BorderThickness="2" BorderBrush="Blue">
<Canvas x:Name="DrawableCanvas">
<Image x:Name="CanvasImage"></Image>
</Canvas>
</Border>
</Grid>
- 1 回答
- 0 關注
- 266 瀏覽
添加回答
舉報