Сохранение измененного изображения в исходном файле с помощью GDI + - PullRequest
4 голосов
/ 31 октября 2008

Я загружал растровое изображение из файла. Когда я попытался сохранить изображение в другой файл, я получил следующую ошибку «Произошла общая ошибка в GDI +». Я считаю, что это потому, что файл заблокирован объектом изображения.

Хорошо, поэтому попытался вызвать функцию Image.Clone. Это все еще блокирует файл.

гм. Затем я пытаюсь загрузить растровое изображение из FileStream и загрузить изображение в память, чтобы GDI + не блокировал файл. Это прекрасно работает, за исключением того, что мне нужно генерировать миниатюры, используя метод Image.GetThumbnailImage, который выдает исключение из нехватки памяти. Очевидно, мне нужно держать поток открытым, чтобы остановить это исключение, но если я оставлю поток открытым, файл останется заблокированным.

Так что нехорошо с этим методом. В конце концов я создал копию файла. Так что теперь у меня есть 2 версии файла. 1 Я могу блокировать и манипулировать в моей программе на C #. Этот другой оригинальный файл остается разблокированным, в который я могу сохранить изменения. Это дает мне преимущество, позволяя мне отменить изменения даже после их сохранения, потому что я манипулирую копией файла, который не может быть изменен.

Конечно, есть лучший способ добиться этого без необходимости иметь 2 версии файла изображения. Есть идеи?

Ответы [ 3 ]

2 голосов
/ 04 ноября 2008

С тех пор я нашел альтернативный метод клонирования изображения без блокировки файла. У Боба Пауэлла есть все, плюс дополнительные ресурсы GDI .

      //open the file
      Image i = Image.FromFile(path);

      //create temporary
      Image t=new Bitmap(i.Width,i.Height);

      //get graphics
      Graphics g=Graphics.FromImage(t);

      //copy original
      g.DrawImage(i,0,0);

      //close original
      i.Dispose();

      //Can now save
      t.Save(path)
2 голосов
/ 31 октября 2008

Ну, если вы ищете другие способы сделать то, что вы просите, я считаю, что это должно сработать, чтобы создать MemoryStream, и прочитать в него FileStream и загрузить изображение из этого потока ...

var stream = new FileStream("original-image", FileMode.Open);
var bufr = new byte[stream.Length];
stream.Read(bufr, 0, (int)stream.Length);
stream.Dispose();

var memstream = new MemoryStream(bufr);
var image = Image.FromStream(memstream);

Или что-то более привлекательное до такой степени.

Независимо от того, нужно ли вам решать эту проблему, я не знаю. :) У меня была похожая проблема, и я все исправил.

1 голос
/ 11 марта 2015

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

    public void SaveHeightmap(string path)
    {
        if (File.Exists(path))
        {
            Bitmap bitmap = new Bitmap(image); //create bitmap from image
            image.Dispose(); //delete image, so the file

            bitmap.Save(path); //save bitmap

            image = (Image) bitmap; //recreate image from bitmap
        }
        else
            //...
    }

Конечно, это не лучший способ, но он работает: -)

...