Как создать bitmap большого размера в C#?
Пытаюсь создать битмап 30к на 30к, но вылетает ArgumentException.
var bitmap = new Bitmap(30000, 30000);
Проблема решила библиотека ImageSharp, но с ней у меня изображения не подгружаются полностью и есть артефакты. Как создать битмап большого размера без доп. библиотек и массива битмапов (одно из решений, что я нашел на SO) ? Если есть способ создать полотно большого размера для размещения картинок на нём, то готов рассмотреть другой способ.
Что я пробовал: прописывал gcallowverylargeobjects = true Приложение: Консоль, .NET 6 (пробовал и .NET 5) Компьютер мощный, ОЗУ должно хватать точно (64гб)
Ответы (1 шт):
Максимальный Bitmap, который вы можете создать с помощью GDI+ может весить максимум int.MaxValue байт. Это ограничение на уровне библиотеки GDI+ и обойти его невозможно, если вы конечно хотите продолжать использовать System.Drawing.
То есть если глубина цвета 32bpp, то размер при ширине 30000
2147483647 / 4 / 30000 = 17895
То есть код
Bitmap bitmap = new Bitmap(30000, 17895, PixelFormat.Format32bppArgb);
Сработает, но можно еще если вам не нужна прозрачность сделать 3 байта на пиксель 24bpp
2147483647 / 3 / 30000 = 23860
Получится так
Bitmap bitmap = new Bitmap(30000, 23860, PixelFormat.Format24bppRgb);
То есть, чтобы покрыть площадь 30000x30000 для полноцветного изображения, вам потребуется как минимум 2 битмапа.
Но если вам цветов надо немного, можно создать 8-битный битмар (1 байт на пиксель) и залить в него свою палитру, если требуется, тогда
2147483647 / 30000 = 71582
То есть код
Bitmap bitmap = new Bitmap(30000, 30000, PixelFormat.Format8bppIndexed);
Сработает без проблем.
Я бы конечно посоветовал область изображения разделить на тайлы, например 10000x10000 пикселей и использовал бы 9 тайлов. Чем меньше битмап - тем быстрее с ним работать.
Кстати, немного арифметики
Console.WriteLine(unchecked(30000 * 30000 * 4)); // -694967296
То есть из-за переполнения int значения, GDI+ получает отрицательное число при расчете размера изображения, отсюда и возникает ArgumentException.