Возможно ли, что исходный поток, поддерживающий исходное изображение, был закрыт? Если поток позади растрового изображения был закрыт, вы начинаете получать ошибки GDI+. Я часто сталкивался с этим, когда мы добавили обработку изображений на наш сайт.
Если вы откроете объект Bitmap в отладчике Visual Studio, увидите ли вы исключения вместо значений свойств? Если да, то проблема не в операции сохранения, а в том, что уровень GDI+ потерял способность обрабатывать объект, и точка.
Я обнаружил, что мне нужно отслеживать потоки памяти, принадлежащие моим растровым изображениям, и хранить их все вместе. Изменение размера изображения привело к созданию нового MemoryStream с новым растровым изображением.
В итоге я создал этот простой класс (обрезав некоторые дополнительные свойства, которые здесь не нужны):
public class UploadedImage : IDisposable
{
private Bitmap _img = null;
private Stream _baseStream = null;
/// <summary>
/// The image object. This must always belong to BaseStream, or weird things can happen.
/// </summary>
public Bitmap Img
{
[DebuggerStepThrough]
get { return _img; }
[DebuggerStepThrough]
set { _img = value; }
}
/// <summary>
/// The stream that stores the image. This must ALWAYS belong to Img, or weird things can happen.
/// </summary>
public Stream BaseStream
{
[DebuggerStepThrough]
get { return _baseStream; }
[DebuggerStepThrough]
set { _baseStream = value; }
}
[DebuggerStepThrough]
public void Dispose()
{
if (Img != null)
Img.Dispose();
if (BaseStream != null)
BaseStream.Close();
_attached = false;
}
}
Теперь я имел дело с изображениями, загруженными на наш веб-сайт, и обнаружил, что, когда Asp.Net перерабатывает поток, прикрепленный к запросу, все операции с изображениями начинают внезапно прерываться. Итак, мое решение, независимо от того, был ли это лучший способ сделать это или нет, состояло в том, чтобы скопировать данные из потока загрузки в мой собственный MemoryStream, загрузить изображение из него и вставить оба в этот контейнер. И где бы я ни создавал новый образ из старого, я всегда сохранял поток и образ вместе.
Надеюсь, это поможет.
РЕДАКТИРОВАТЬ: мне также интересно посмотреть, как вы изменяете размер изображения. Это фрагмент того, как я сделал наш:
temp = new Bitmap(newWidth, newHeight, PIXEL_FORMAT);
temp.SetResolution(newHorizontalRes, newVerticalRes);
gr = Graphics.FromImage(temp);
//
// This copies the active frame from 'img' to the new 'temp' bitmap.
// Also resizes it and makes it super shiny. Sparkle on, mr image dude.
//
Rectangle rect = new Rectangle(0, 0, newWidth, newHeight);
gr.InterpolationMode = InterpolationMode.HighQualityBicubic;
gr.SmoothingMode = SmoothingMode.HighSpeed;
gr.PageUnit = GraphicsUnit.Pixel;
gr.DrawImage(img, rect);
//
// Image copied onto the new bitmap. Save the bitmap to a fresh memory stream.
//
retval = new UploadedImage();
retval.BaseStream = (Stream)(new MemoryStream());
temp.Save(retval.BaseStream, ImageFormat.Jpeg);
retval.Img = temp;
person
Community
schedule
04.08.2009