Невозможно перезаписать загруженные изображения в C # с помощью объекта Image - PullRequest
0 голосов
/ 31 июля 2009

Я пытаюсь создать утилиту в C # с использованием инфраструктуры MVC, где пользователь загружает изображение, которое используется для обрезки кусочков, чтобы использовать его в качестве значков миниатюр (только один пользователь будет делать это одновременно) время). Затем пользователь может загрузить другое изображение и продолжить обрезку.

У меня есть действие контроллера, которое обрабатывает загрузку файла, делая снимок, конвертируя его из любого формата в формат JPEG и сохраняя его как «temp.jpg» (я знаю, что это не тонкий контроллер, но это только для цели тестирования). Когда они загружают следующее изображение, я хочу заменить этот файл temp.jpg новым. Этот контроллер отлично работает в разработке на моей машине, но в производстве после того, как пользователь загрузит первое изображение и попытается заменить его другим изображением, он получит следующую ошибку:

"процесс не может получить доступ к файлу, потому что он используется другим процессом"

Мне кажется, что файл "temp.jpg" блокируется после первой загрузки, и я не могу понять, как этого избежать.

Любые предложения или альтернативные идеи приветствуются.

Описание того, что делает мой код:

  • Проверяет, будет ли загружено изображение существует на сервере и удаляет его, если найдено
  • Сохраняет картинку как есть с это оригинальное имя файла и расширение
  • Проверяет файл "temp.jpg" и удаляет его, если найден
  • Открывает исходное изображение в объекте System.Drawing.Image для преобразования в формат JPEG
  • Сохраните его как новый файл «temp.jpg» для замены удаленного файла.

Мой код:

        [AcceptVerbs(HttpVerbs.Post)]
    public ActionResult PicUpload(DateTime sd, FormCollection collection)
    {
            foreach (string file in Request.Files)
            {
                HttpPostedFileBase hpf = Request.Files[file] as HttpPostedFileBase;
                    if (hpf.ContentLength == 0)
                        continue;
                    string savedFileName = Path.Combine(
                       AppDomain.CurrentDomain.BaseDirectory + "Content\\AdContent\\",
                       Path.GetFileName(hpf.FileName));

                    FileInfo temp = new FileInfo(savedFileName);
                    if (temp.Exists) temp.Delete();

                    hpf.SaveAs(savedFileName);

                    string tempFileName = AppDomain.CurrentDomain.BaseDirectory + "Content\\AdContent\\temp.jpg";

                    temp = new FileInfo(tempFileName);
                    if (temp.Exists) temp.Delete();

                    EncoderParameters codecParams = new EncoderParameters(1);
                    codecParams.Param[0] = new EncoderParameter(Encoder.Quality, 100L);
                    ImageCodecInfo[] encoders;
                    encoders = ImageCodecInfo.GetImageEncoders();

                    Image newPic = Image.FromFile(savedFileName);
                    newPic.Save(tempFileName, encoders[1], codecParams);
                    newPic.Dispose();

                    FileInfo tmp = new FileInfo(savedFileName);
                    if (tmp.Exists) tmp.Delete();
                    return RedirectToAction("Create", new { startdate = String.Format("{0:MM-dd-yyyy}", sd) });
            }
            return RedirectToAction("Create", new { startdate = String.Format("{0:MM-dd-yyyy}", sd) });
    }

Ответы [ 4 ]

2 голосов
/ 31 июля 2009

Оказывается, я не освобождаю ресурсы изображения должным образом в другом разделе моего кода, который возвращал свойства ширины и высоты изображения. Также вместо того, чтобы использовать метод Dispose();, я вместо этого помещаю код в «блок использования» следующим образом:

            using (Image newPic = Image.FromFile(savedFileName))
            {
                newPic.Save(tempFileName, encoders[1], codecParams);
            }

Это сработало как талисман, и теперь я могу безнаказанно удалять файл temp.jpg.

1 голос
/ 31 июля 2009

Используйте элемент управления "панель" и сохраните его как BMP, PNG, как угодно

1 голос
/ 31 июля 2009

System.Drawing.Image.Save () не может сохранить в том же месте, откуда был открыт файл:

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

0 голосов
/ 31 июля 2009

Вы можете использовать временный файл с уникальным именем для tempFileName вместо «temp.jpg». System.IO.Path имеет метод GetTempFileName(), который вы можете использовать для этого.

Другой вариант - использовать метод GetRandomFileName() (также в System.IO.Path), который возвращает случайный путь или имя файла, тогда нужно просто внести небольшое изменение в ваш код:

- string tempFileName = AppDomain.CurrentDomain.BaseDirectory + "Content\\AdContent\\temp.jpg";
+ string tempFileName = AppDomain.CurrentDomain.BaseDirectory + "Content\\AdContent\\" + System.IO.Path.GetRandomFileName();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...