WPF, часто картинка refre sh без мерцания - PullRequest
0 голосов
/ 20 февраля 2020

Я пытаюсь создать «живое изображение» с моей веб-камеры с помощью WPF, которое дает мне только снимки JPG через HTTP. Каждый раз, когда я обновляю источник изображения, он мерцает. У кого-нибудь есть идеи, как это исправить?

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 ]

2 голосов
/ 20 февраля 2020

Мерцание вызвано тем, что BitmapImage загружается асинхронно, то есть после того, как вы присвоили его свойству Source источника изображения. Элемент Image сначала становится пустым и будет отображать изображение только после завершения загрузки.

В этом случае вы можете установить свойство Source в обработчике 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;
    }
}
1 голос
/ 20 февраля 2020

Спасибо @all за помощь. Получил решение от Обновление BitmapImage каждую секунду мерцает

Преобразован в асинхронный c 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;
    }
}
...