Почему закрытие потока памяти, используемого для создания объекта Image, влияет на новый объект Image?C#

Место общения программистов C#
Ответить Пред. темаСлед. тема
Anonymous
 Почему закрытие потока памяти, используемого для создания объекта Image, влияет на новый объект Image?

Сообщение Anonymous »

Вопрос:
Почему объект MemoryStream, используемый для ImageA, влияет на клонированный объект Image с именем ImageB? Я знаю, что Microsoft говорит, что когда вы создаете объект изображения из потока памяти, вы должны оставить этот поток открытым на весь срок службы изображения. Но я пытаюсь создать ImageA из MemoryStream, клонировать ImageA в ImageB, затем избавиться от ImageA и MemoryStream, использованных для создания ImageA. После этого я получаю ошибки при работе с ImageB.
Примеры исходного кода:
Весь приведенный ниже код используется для создания нового многостраничного изображения в формате tiff из 3 tiff-файлы (одна страница). В итоге вы получите одно изображение в формате tiff, занимающее 3 страницы.
От этого вы получите...
  • Image newImg
  • MemoryStream ms
Примечание. Это может показаться большим количеством кода для небольшого теста, но я хотел привести действительно хороший пример того, где Я получаю объекты, с которыми работаю. Большая часть кода этого примера была взята из нескольких различных методов/функций, и я просто изменил несколько вещей, чтобы по-настоящему нарисовать картину всего, что я делаю при импорте самого файла.
Image img = Image.FromFile(@"c:\test\page001.tif");
MemoryStream ms = new MemoryStream();
List imagesToAdd = new List()
{
Image.FromFile(@"c:\test\page002.tif"),
Image.FromFile(@"c:\test\page003.tif")
};

// Create compression encoder parameter
EncoderParameter compressionParam = new EncoderParameter(Encoder.Compression, (long)EncoderValue.CompressionCCITT4);

// Create first page frame parameter
EncoderParameter firstFrameParam = new EncoderParameter(Encoder.SaveFlag, (long)EncoderValue.MultiFrame);

// Create additional pages frame parameter
EncoderParameter additionalFramesParam = new EncoderParameter(Encoder.SaveFlag, (long)EncoderValue.FrameDimensionPage);

// Create color depth parameter
EncoderParameter colorDepthParam = new EncoderParameter(Encoder.ColorDepth, (long)1);

// Create flush parameter
EncoderParameter flushParam = new EncoderParameter(Encoder.SaveFlag, (long)EncoderValue.Flush);

// Create last frame parameter
EncoderParameter lastPageParam = new EncoderParameter(Encoder.SaveFlag, (long)EncoderValue.LastFrame);

// Create first page encoder parameters
EncoderParameters firstFrameParams = new EncoderParameters(2)
{
Param = new EncoderParameter[]
{
compressionParam,
firstFrameParam,
}
};

// Create additional pages encoder parameters
EncoderParameters additionalFrameParams = new EncoderParameters(2)
{
Param = new EncoderParameter[]
{
compressionParam,
additionalFramesParam,
}
};

// Create save to file encoder parameters
EncoderParameters saveToFileParams = new EncoderParameters(2)
{
Param = new EncoderParameter[]
{
compressionParam,
colorDepthParam,
}
};

// Create flush encoder parameters
EncoderParameters flushParams = new EncoderParameters(1)
{
Param = new EncoderParameter[]
{
flushParam,
lastPageParam,
}
};

// Get the tiff image codec
ImageCodecInfo codec = ImageCodecInfo.GetImageEncoders().Where(c => c.MimeType == "image/tiff").First();

// Save the first page to memory stream
img.Save(ms, codec, firstFrameParams);

// Save aditional pages to memory stream
foreach (Image image in imagesToAdd)
img.SaveAdd(image, additionalFrameParams);

// Finalize the new multi-page image
img.SaveAdd(flushParams);

//Image newImg = pageOne.SaveMultiPageImage(imgCol, out MemoryStream ms);
Image newImg = Image.FromStream(ms);

// Cleanup
firstFrameParams.Dispose();
additionalFrameParams.Dispose();
saveToFileParams.Dispose();
flushParam.Dispose();
compressionParam.Dispose();
firstFrameParam.Dispose();
additionalFramesParam.Dispose();
colorDepthParam.Dispose();
flushParam.Dispose();
lastPageParam.Dispose();

Приведенный ниже код действительно используется в другом месте. Я сделал всю эту функцию для тестирования, чтобы показать хороший пример. Идея приведенного ниже кода состоит в том, чтобы работать с изображением, созданным с помощью приведенного выше кода, затем создать его клон, удалить исходное изображение и поток памяти, использованный для его создания, а затем попытаться поработать с вновь созданным объектом изображения.
Проблема: после удаления потока памяти, использованного для создания объекта изображения newImg, новое изображение (newImg2), клонированное из newImg, становится поврежденным.
// Try to work with the newImg Image object (no issues)
int pageCount = newImg.GetFrameCount(FrameDimension.Page);
for (int i = 0; i < pageCount; i++)
{
newImg.SelectActiveFrame(FrameDimension.Page, i);
Debug.WriteLine($"BEFORE - Page:{i + 1} W/H: {newImg.Width}/{newImg.Height}");
}

// Create a new Image (newImg2) based on the original Image (newImg)
// then dispose of the original Image object as it's no longer needed
Image newImg2 = (Image)newImg.Clone();
newImg.Dispose();

// This causes issues when dealing with newImg2 going forward
ms.Dispose();

// Try to work with the newImg2 Image object (issues)
pageCount = newImg2.GetFrameCount(FrameDimension.Page);
for (int i = 0; i < pageCount; i++)
{
newImg2.SelectActiveFrame(FrameDimension.Page, i);
Debug.WriteLine($"AFTER - Page:{i + 1} W/H: {newImg2.Width}/{newImg2.Height}");
}


Подробнее здесь: https://stackoverflow.com/questions/791 ... -a-new-ima
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «C#»