Я работаю с большими изображениями размера (для напр. 16000x9440 пкс) и сокращение некоторые регионы для других вещей. Я вытаскиваю исключение "Из памяти", когда создают новый Растровый экземпляр:
using (FileStream fileStream = new FileStream(mapFileResized, FileMode.Open))
{
byte[] data = new byte[fileStream.Length];
fileStream.Read(data, 0, data.Length);
using (MemoryStream memoryStream = new MemoryStream(data))
{
using (Bitmap src = new Bitmap(memoryStream)) // <-- exception
{
tile = new Bitmap(tileWidth, tileHeight, PixelFormat.Format24bppRgb);
tile.SetResolution(src.HorizontalResolution, src.VerticalResolution);
tile.MakeTransparent();
using (Graphics grRect = Graphics.FromImage(tile))
{
grRect.CompositingQuality = CompositingQuality.HighQuality;
grRect.SmoothingMode = SmoothingMode.HighQuality;
grRect.DrawImage(
src,
new RectangleF(0, 0, tileWidth, tileHeight),
rTile,
GraphicsUnit.Pixel
);
}
}
}
}
Когда я использую небольшие размеры изображения (для напр. 8000x4720 пкс), затем все хорошо работают.
Как я могу работать с большими изображениями размера?
Битовый массив мозаики PS расположен в наконец блоке.
С наилучшими пожеланиями, Alex.
Вы используете около гигабайта оперативной памяти, поэтому неудивительно, что у вас закончилась память.
Предполагая, что вы используете формат файла 32bpp с 16000x9440 пикселей, вы получите размер файла примерно:
16000 * 9440 * (32/8) = ~ 576MB
byte[] data = new byte[fileStream.Length];
fileStream.Read(data, 0, data.Length);
using (MemoryStream memoryStream = new MemoryStream(data))
{
[... snip ...]
}
Вы загружаете весь файл в поток памяти, для этого требуется 576MB .
[... snip ...]
using (Bitmap src = new Bitmap(memoryStream)) // <-- exception
{
[... snip ...]
}
[... snip ...]
Вы загружаете все содержимое потока в растровое изображение, для этого требуется еще как минимум 576 МБ (в зависимости от того, сколько памяти требует растровое изображение на пиксель, должно быть не менее 4, а возможно и больше). В этот момент у вас в памяти дважды остается изображение, что серьезно сказывается на таких больших изображениях.
Вы можете уменьшить объем памяти, избавившись от потока памяти и загрузив растровое изображение непосредственно из файлового потока.
Другим решением было бы загрузить только часть растрового изображения и загрузить другие части по запросу (во многом как карты Google), но я не могу помочь вам с этим решением, может потребоваться чтение растрового изображения вручную.
Не полный ответ на ваш вопрос, но вам, вероятно, лучше использовать такую библиотеку, как ImageMagick.NET
MemoryStream
реализован с использованием массива байтов, в котором хранятся данные. Если вы читаете больше данных, чем может вместить массив, выделяется новый массив двойного размера и байты копируются из одного массива в другой.
Поскольку вы, очевидно, знаете, сколько данных вам понадобится, вы можете выделить правильный размер заранее и таким образом избежать изменения размера.
Однако, как только вы достигнете определенного размера, у вас закончится память. .NET налагает ограничение в 2 ГБ на один объект ( даже на 64-битном ), поэтому внутренний массив в MemoryStream
никогда не сможет вырасти сверх этого. Если ваше изображение больше, вы получите исключение нехватки памяти.