Откройте изображение из файла, а затем отпустите блокировку?


я использую следующую строку кода, чтобы открыть Image из файла:

pictureBox1.Image = Image.FromFile("test.png");

Я ожидаю, что он заблокирует файл, загрузит изображение в память, установит pictureBox1.Image к копии в памяти и отпустите блокировку. На самом деле, замок не уйдет, пока я Dispose() на Image в памяти. Я не могу освободить блокировку файла на жестком диске, который я больше не использую, пока не избавлюсь от файла в что я am использование.
Майкрософта сайт упоминает об этом в статье с меткой C#, но их решение написано в visual basic, что для меня бесполезно.

в резюме: Я хочу установить pictureBox1.Image к изображению, хранящемуся в "test.png", то пусть пользователь редактировать или удалять "test.png" или что-то еще.

5 55

5 ответов:

подход с потоком не исправим.

смотрите здесь https://stackoverflow.com/a/8701748/355264

правильный код сверху ссылка:

Image img;
using (var bmpTemp = new Bitmap("image_file_path"))
{
    img = new Bitmap(bmpTemp);
}

или еще лучше, использовать using оператор (код ниже в противном случае копируется из сообщения sylon [deleted]). Таким образом, если Image.FromStream выбрасывает исключение, вы все еще можете быть уверены, что поток немедленно закрыт.

using (FileStream stream = new FileStream("test.png", FileMode.Open, FileAccess.Read))
{
    pictureBox1.Image = Image.FromStream(stream);
}

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

FileStream stream = new FileStream("test.png", FileMode.Open, FileAccess.Read);
pictureBox1.Image = Image.FromStream(stream);
stream.Close();

самый простой способ, который я нашел, - это заморозить объект, содержащий источник (путь к файлу). Все элементы управления, которые могут содержать изображение, кажется, есть .Источник, который, если не null, он заблокирует файл, на который он указывает.

теперь трюк состоит в том, чтобы изменить элемент управления Image в состояние "только для чтения", которое затем разблокирует файл.

мое решение:

    private Image CreatePreviewImage()
    {
        Image ReportImage = new Image();
        Uri path = new Uri(@"C:\Folder\Image1.png");
        if (File.Exists(path.OriginalString))
        {
            ReportImage.Name = "Report1";
            ReportImage.Source = LoadImageFromFile(path);
        }
        return ReportImage;
    }

    public ImageSource LoadImageFromFile(Uri path)
    {
        BitmapImage bitmap = new BitmapImage();
        bitmap.BeginInit();
        bitmap.UriSource = path;
        bitmap.CacheOption = BitmapCacheOption.OnLoad;
        bitmap.CreateOptions = BitmapCreateOptions.IgnoreImageCache;
        bitmap.DecodePixelWidth = 900;
        bitmap.EndInit();
        bitmap.Freeze(); //This is the magic line that releases/unlocks the file.
        return bitmap;
    }

говорить открытый, читать и выпускать

    StreamReader streamReader = new StreamReader("picture.png");
    Bitmap tmpBitmap = (Bitmap)Bitmap.FromStream(streamReader.BaseStream);
    streamReader.Close();
    pictureBox1.Image = tmpBitmap;`