亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

在 WPF 畫布中編寫數千筆畫的最佳方式

在 WPF 畫布中編寫數千筆畫的最佳方式

C#
慕的地8271018 2021-08-22 18:03:59
我必須通過在 Wacom 平板電腦(如在紙上)上觸摸來實現書寫,并且我需要在 WPF Canvas 中每秒渲染多達 200 個筆畫。問題是,經過大約 20 秒的持續寫入后,它會變得有點滯后,并且滯后會增加。我將所有筆畫存儲在HashSet 中。當 HashSet 包含超過 600 個元素并將其設置為背景圖像并清除 HashSet 時,我想進行屏幕拍攝,但是在大約 30 次屏幕拍攝后它變得有點模糊。你知道如何讓它變得更好嗎?
查看完整描述

1 回答

?
MM們

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>


查看完整回答
反對 回復 2021-08-22
  • 1 回答
  • 0 關注
  • 266 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號