(C #) graphics.drawImage имеет ограничение по размеру? Как с этим бороться? - PullRequest
4 голосов
/ 08 апреля 2010

Я пытаюсь отобразить очень большое графическое представление некоторых данных. Я использую растровое изображение для постоянного хранения изображения и e.Graphics.DrawImage(myBitmap, new Point(0,0)) в onPaint элемента управления PictureBox на моей форме. Я заметил (и слышал упомянутое на других сайтах), что если мое изображение имеет высоту или ширину больше 2 ^ 15, я получаю исключение Parameter not Valid, но я не нашел официальной документации по этому пределу.

Является ли ограничение размера 2 ^ 15 определенной, официальной частью Graphics.DrawImage? Есть ли какие-нибудь простые обходные пути для рендеринга всего моего изображения в форму?

(Да, для PictureBox установлен тот же размер, что и для изображения, или больше. Тем не менее, дополнительный вопрос, должен ли я использовать onPaint самой формы вместо графического блока?)

Ответы [ 3 ]

5 голосов
/ 18 июня 2010

У вас есть несколько вопросов здесь. Во-первых, принципиально невозможно отобразить изображение такого большого размера (если только у вас не установлен какой-то безумно огромный монитор или несколько мониторов), не уменьшив его до размера, который поместится на обычном экране.

Вы можете выполнить это уменьшение размера, используя Graphics.DrawImage, но имейте в виду, что даже при высоком качестве InterpolationMode интерполяция выполняется не более чем на нескольких соседних пикселях, что означает, что ограничение Максимальное количество, которое вы можете уменьшить изображение без серьезной потери информации (обычно до 25%).

Во-вторых, объект Bitmap в .Net намного сложнее, чем простой массив пикселей. Иногда растровые изображения создаются в видеопамяти вместо общей памяти программ, что ограничивает их максимальный размер более жестко (например, в компактной среде один из конструкторов растровых изображений создает данные пикселей в видеопамяти, которая ограничена 4 МБ вместо 32 МБ, обычно доступный для процесса .NET). В результате не задокументирован максимальный размер для Bitmap - это внутренняя деталь реализации (затронутая также любыми уже существующими растровыми изображениями), которую программист может обнаружить только трудным путем, получив выброшенное исключение, если оно слишком большой. Поэтому использование Bitmap для хранения произвольно большого набора точек данных не сработает.

Ваш лучший подход здесь, вероятно, заключался бы в том, чтобы хранить ваши данные в виде обычного двумерного массива (типа int[,], вероятно), который мог бы быть произвольно большим без броска OutOfMemoryException (хотя и без заставления вашего компьютера работать swapfile-crazy), а затем напишите собственный метод, который копирует из этого массива в фактический (и практически размер) Bitmap. Затем вы скопируете из этого Bitmap в PictureBox (или, проще говоря, просто установите это Bitmap в качестве свойства Image графического блока - лучше по возможности избегать метода Paint).

2 голосов
/ 08 апреля 2010

Вы столкнетесь с проблемой задолго до того, как достигнете этого предела, примерно в 10000x10000 пикселей вы будете использовать почти всю свою память для своего растрового изображения. Учтите, что внутреннее растровое изображение gdi + будет 32bppargb, по моим расчетам, 4 байта на пиксель x 100000000 = 4 ГБ.

Вы должны разбить изображение на плитки или, если вы рисуете это, вручную реализовать решение для подкачки.

1 голос
/ 06 марта 2015

Мне удалось создать растровые изображения до 25200 на 15000 пикселей с использованием C # и форм Windows в 64-битном приложении. Я все еще экспериментирую, но кажется, что это примерно предел размера растрового изображения.

...