Манипуляции с JPEG и dotnet - исключение GDI + - PullRequest
1 голос
/ 22 января 2012

Например, вот пример JPEG, который я не могу СОХРАНИТЬ (!), Но могу прочитать (например, узнать ширину и высоту), используя стандартные классы dotnet.Исходный файл:

http://dl.dropbox.com/u/5079317/184809_1_original.jpg

После сохранения того же изображения в редакторе изображений Windows все прекрасно работает: http://dl.dropbox.com/u/5079317/184809_1_resaved.jpg

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

Какие сторонние библиотеки можно использовать?

Вот как я читаю:

public ImageFile SaveImage(HttpPostedFileBase file, string fileNameWithPath, bool splitImage, out string errorMessage)
{
  try
  {
    using (var stream = file.InputStream)
    {
      using (Image source = Image.FromStream(stream))
      {
        return SaveImage(source, fileNameWithPath, splitImage, out errorMessage);
        // which actually do source.Save(fileNameWithPath, ImageFormat.Jpeg);
        // Exception: A generic error occurred in GDI+.
      }
    }
  }
  catch (Exception e)
  ...
}

Ответы [ 3 ]

0 голосов
/ 22 января 2012

Iirc нужно искать в некоторых форматах, что поддерживается не во всех потоках.Вы можете попробовать буферизацию в потоке памяти:

using (var input = file.InputStream)
using (var buffer = new MemoryStream())
{
    input.CopyTo(buffer);
    buffer.Position = 0; // rewind
    using (Image source = Image.FromStream(buffer))
    { ... Etc  as before ... }
}
0 голосов
/ 16 февраля 2012

Изменение размера исходного изображения до такого же размера решает проблему:

Image img2 = FixedSize(source, source.Width, source.Height, true);
img2.Save(path, ImageFormat.Jpeg);
0 голосов
/ 22 января 2012

Я не уверен, какую библиотеку вы используете для SaveImage, но если вы просто используете .NET, вызовите следующий метод Save (с пустым типом возврата) для объекта Image и верните любой объект, который вам нужендля объекта System.Drawing.Image из вашего нового файла.

source.Save(@"C:\{path}\184809_1_resaved.jpg", System.Drawing.Imaging.ImageFormat.Jpeg);

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

public System.IO.Stream SaveImage(HttpPostedFileBase file, string fileNameWithPath, bool splitImage, out string errorMessage)
{
    try
    {
        using (var stream = file.InputStream)
        {
            using (System.Drawing.Image source = System.Drawing.Image.FromStream(stream))
            {
                source.Save(@"C:\resaved.jpg", ImageFormat.Jpeg);
                source.Save(stream, ImageFormat.Jpeg);
                stream.Position = 0;
                errorMessage = string.Empty;
                return stream;
            }
        }
    }
    catch (Exception e)
    {
        errorMessage = e.Message.ToString();
    }
    return null;
}
...