WPF,图片经常刷新而不闪烁

时间:2020-02-20 10:04:33

标签: c# wpf xaml bitmapimage

我正在尝试使用WPF从我的网络摄像头创建“实时取景”,这只能通过HTTP给我JPG快照。 每次更新图像源时,都会闪烁。 有人知道如何解决此问题吗?

XAML:

     <Grid>
        <Image Name="img"/>
    </Grid>

C#:

public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            DispatcherTimer timer = new DispatcherTimer();
            timer.Interval = TimeSpan.FromMilliseconds(1000.0);
            timer.Tick += timer_Tick;
            timer.Start();

        }

        void timer_Tick(object sender, EventArgs e)
        {

            BitmapImage _image = new BitmapImage();
            _image.BeginInit();
            _image.CacheOption = BitmapCacheOption.None;
            _image.UriCachePolicy = new RequestCachePolicy(RequestCacheLevel.BypassCache);
            _image.CacheOption = BitmapCacheOption.OnLoad;
            _image.CreateOptions = BitmapCreateOptions.IgnoreImageCache;
            _image.UriSource = new Uri(@"http://0.0.0.0/api/camera/snapshot?width=640&height=480", UriKind.RelativeOrAbsolute);
            _image.EndInit();
            img.Source = _image;
        }
    }

2 个答案:

答案 0 :(得分:2)

闪烁是因为BitmapImage是异步加载的,即在将其分配给Image的Source属性之后。 Image元素首先变为空,并且仅在下载完成后才会显示图像。

在这种情况下,您可以在DownloadCompleted事件处理程序中设置void timer_Tick(object sender, EventArgs e) { var uri = "http://0.0.0.0/api/camera/snapshot?width=640&height=480"; var image = new BitmapImage(); image.BeginInit(); image.CreateOptions = BitmapCreateOptions.IgnoreImageCache; image.UriCachePolicy = new RequestCachePolicy(RequestCacheLevel.BypassCache); image.UriSource = new Uri(uri); image.EndInit(); if (image.IsDownloading) { image.DownloadCompleted += (s, ev) => img.Source = image; } else { img.Source = image; } } 属性:

std::unique_ptr<Base>

答案 1 :(得分:1)

感谢@all的帮助。 从Update BitmapImage every second flickers

获得了解决方案

转换为异步HttpClient API而不是WebClient,它看起来像:

private readonly HttpClient httpClient = new HttpClient();

private async void timer_Tick(object sender, EventArgs e)
{
    var uri = "http://0.0.0.0/api/camera/snapshot?width=640&height=480";

    using (var responseStream = await httpClient.GetStreamAsync(uri))
    using (var memoryStream = new MemoryStream())
    {
        await responseStream.CopyToAsync(memoryStream); // ensure full download

        BitmapImage image = new BitmapImage();
        image.BeginInit();
        image.CacheOption = BitmapCacheOption.OnLoad;
        image.StreamSource = memoryStream;
        image.EndInit();
        img.Source = image;
    }
}