Странное поведение GDI + - PullRequest
       6

Странное поведение GDI +

0 голосов
/ 10 октября 2009

Я сделал метод CompressImageSize в соответствии с качеством изображения. Код для этого

public static Image CompressImage(string imagePath, long quality)
{
    Image srcImg = LoadImage(imagePath);
    //Image srcImg = Image.FromFile(imagePath);

    EncoderParameters parameters = new EncoderParameters(1);
    parameters.Param[0] = new EncoderParameter(Encoder.Quality, quality);

    ImageCodecInfo encoder = GetCodecInfo("image/jpeg");

    srcImg.Save("d:\\creatives\\abcd123.jpg", encoder, parameters);
}

public static Image LoadImage(string filename)
{
    using (FileStream fs = new FileStream(filename, FileMode.Open))
    {
        return(Image.FromStream(fs));
    }
}

Теперь, когда я запускаю этот код как есть, он дает мне «Generic GDI + исключение» при сохранении srcImg (последняя строка в функции # 1), НО, когда я раскомментирую 2-ю строку и загружаю изображение, используя Image.FromFile отлично работает.

Почему ??

Ответы [ 6 ]

3 голосов
/ 10 октября 2009

Согласно MSDN :

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

Здесь ваш поток находится в блоке использования и поэтому закрыт до конца времени жизни изображения.

0 голосов
/ 21 октября 2009

Исправлено, но для меня вызов Dispose - это ошибка в .net framework ...

public static Image CompressImage(string imagePath, long quality)
{
    Image srcImg = LoadImage(imagePath);
    //Image srcImg = Image.FromFile(imagePath);

    EncoderParameters parameters = new EncoderParameters(1);
    parameters.Param[0] = new EncoderParameter(Encoder.Quality, quality);

    ImageCodecInfo encoder = GetCodecInfo("image/jpeg");

    srcImg.Save("d:\\creatives\\abcd123.jpg", encoder, parameters);
srcImg.Dispose();
}
0 голосов
/ 10 октября 2009

Существуют различные проблемы с Image.FromFile () ...

Image srcImg = Image.FromFile(imagePath);

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

public static Image CompressImage(string imagePath, long quality)
{
    using(FileStream fs = File.OpenRead(imagePath)){
       Image srcImg = Image.FromStream(fs);    

       EncoderParameters parameters = new EncoderParameters(1);    
       parameters.Param[0] = new EncoderParameter(Encoder.Quality, quality);    
       ImageCodecInfo encoder = GetCodecInfo("image/jpeg");    
       srcImg.Save("d:\\creatives\\abcd123.jpg", encoder, parameters);
    }
}

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

0 голосов
/ 10 октября 2009

Вы должны переписать свой код:

public static Image LoadImage(string filename)
{
    FileStream fs = new FileStream(filename, FileMode.Open);        
    return Image.FromStream(fs);        
}

Конструкция using неверна в этом случае, потому что FileStream должен быть жив для использования вашего изображения.

0 голосов
/ 10 октября 2009

В конце LoadImage FileStream, содержащий изображение, удаляется. Это слишком рано; поток файла должен быть живым для использования методом, вызывающим LoadImage.

См. , используя в MSDN.

0 голосов
/ 10 октября 2009

Дикая догадка ... Изображение IDisposable. Вы называете это в цикле или что-то? Попробуйте поместить само изображение в блок using ()?

...