Почему объект 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