Редактировать файл после удаления привязки

#c# #wpf #data-binding

#c# #wpf #привязка данных

Вопрос:

Я пытаюсь передать экран рабочего стола с одного компьютера на другой. Я начал с простой отправки изображения, что было действительно просто. Моей следующей мыслью было просто отобразить изображение с помощью WPF и, постоянно редактируя сохраненное изображение, я бы получил прямую трансляцию рабочего стола. Попробовав это, я заметил, что редактирование изображения, которое используется в данный момент, приводит к исключению.

Процесс не может получить доступ к файлу ‘D:DesktopConsoleApp1WpfApp1imgBild1.jpeg ‘ потому что он используется другим процессом.

Итак, когда я попытался использовать два разных изображения, которые просто менялись бы местами каждый раз, продолжало появляться одно и то же исключение.

Приведенный ниже код удаляет несвязанное изображение и создает новый файл, который будет привязан к Image .

 // The Image that is currently not binded will be deleted with the code below

if (img1){
    if (File.Exists("./../../img/Bild2.jpeg"))
    {
        File.Delete("./../../img/Bild2.jpeg");
    }
}
else
{
    if (File.Exists("./../../img/Bild1.jpeg"))
    {
        File.Delete("./../../img/Bild1.jpeg");
    }
}

// This code save the Image
if (File.Exists("../../img/Bild1.jpeg")) // Image1 exists so I am editing image2
{
    bmp.Save("../../img/Bild2.jpeg", ImageFormat.Jpeg); 
    ms.Position = 0;
    FileInfo fi = new FileInfo("../../img/Bild2.jpeg");
    ImageBind = fi.FullName; // Image Bind is a string property which is binded to a Image Tag
    img1 = false; // To check which img has been edited last
}
else if (File.Exists("../../img/Bild2.jpeg"))
{
    bmp.Save("./../../img/Bild1.jpeg", ImageFormat.Jpeg);
    ms.Position = 0;
    FileInfo fi = new FileInfo("../../img/Bild1.jpeg");
    ImageBind = fi.FullName; 
    img1 = true; 
}
else // If neither Image1 or Image2 exists
{
    bmp.Save("../../img/Bild1.jpeg", ImageFormat.Jpeg);
    ms.Position = 0;
    FileInfo fi = new FileInfo("../../img/Bild1.jpeg");
    ImageBind = fi.FullName; 
    img1 = true; 
}
  

Комментарии:

1. я думаю, что у меня была похожая проблема, часто решение связано с тем, как работают изображения в c #, они открывают потоки файлов, их не так просто просто поменять местами и переключить, потому что, пока поток открыт, они генерируют это исключение. Возможно, работа с этим может вам помочь. (просто идея)

Ответ №1:

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

Файлы изображений, которым вы назначаете путь к файлу Image , заблокированы до завершения работы приложения. Чтобы изменить это, вам нужно изменить параметры кэширования базового BitmapImage .

Для этого вы можете создать преобразователь значений, чтобы сохранить ImageBind свойство как string .

 public class PathToBitmapSourceConverter : IValueConverter
{
   public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
   {
      var bi = new BitmapImage();
      var uriString = (string)value;

      bi.BeginInit();
      bi.UriSource = new Uri(uriString, UriKind.RelativeOrAbsolute);
      bi.CacheOption = BitmapCacheOption.OnLoad;
      bi.CreateOptions = BitmapCreateOptions.IgnoreImageCache;
      bi.EndInit();

      return bi;
   }

   public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
   {
      throw new InvalidOperationException();
   }
}
  

Этот код преобразует ваш путь к файлу в BitmapImage . OnLoad И IgnoreImageCache предотвратят блокировку изображения. Из документации:

  • OnLoad — Кэширует все изображение в память во время загрузки. Все запросы на данные изображения заполняются из хранилища памяти.
  • IgnoreImageCache — Загружает изображения без использования существующего кэша изображений. Этот параметр следует выбирать только тогда, когда изображения в кэше необходимо обновить.

В вашем XAML вы должны создать экземпляр конвертера в любом словаре ресурсов и адаптировать привязку вашего Image для использования конвертера, предполагая, что его ключ PathToBitmapSourceConverter .

 <Image Source="{Binding ImageBind, Converter={StaticResource PathToBitmapSourceConverter}}" ... />
  

Комментарии:

1. Я не профессионал в этом, и это была моя первая попытка потоковой передачи чего-либо. Не могли бы вы оставить какие-либо предложения о том, как я мог бы улучшить свой проект? Было бы очень мило с вашей стороны, если бы вы могли дать мне несколько советов о том, как улучшить качество потоковой передачи. Спасибо 🙂

2. @LukasSokcevic Мне жаль, но, к сожалению, на это нет короткого ответа. Потоковое видео и аудио — очень сложная тема, особенно по сетям или Интернету. Для этого существуют специализированные протоколы, но это тоже не тривиально.