Исключения при работе с большими изображениями - PullRequest
1 голос
/ 18 января 2012

Я работаю над генератором лабиринтов в C #, который генерирует большие лабиринты, а затем сохраняет их в png-файле.

В настоящее время у меня возникают ошибки при попытке сохранить изображение.

Когда я использую это:

System.Drawing.Bitmap tempBitmap = new System.Drawing.Bitmap(16000, 16000);

Я получаю исключение аргумента. (Работает с 8000 * 8000)

Когда я использую способ WPF:

RenderTargetBitmap rtb = 
              new RenderTargetBitmap(16000, 16000, 96, 96, PixelFormats.Pbgra32);

Я получаю исключение переполнения памяти.

У кого-нибудь есть другой способ сохранить большие изображения в c #?

Я тоже смотрел некоторые библиотеки безуспешно.

Кто-то также сказал, что я должен сначала сохранить изображение по частям, а затем объединить их, но как я могу это сделать?

Edit:

Edit2: Я сейчас пытаюсь PixelFormat.Format1bppIndexed, как это:

private Bitmap CreateBitmapImage2(BitArray[] map, List<Point> path)
{
    Bitmap objBmpImage = new Bitmap(cursize * (map[0].Length - 1), cursize * (map.Length - 1), PixelFormat.Format1bppIndexed);

    Rectangle rect = new Rectangle(0, 0, objBmpImage.Width, objBmpImage.Height);
    System.Drawing.Imaging.BitmapData bmpData =
        objBmpImage.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite,
        objBmpImage.PixelFormat);

    IntPtr ptr = bmpData.Scan0;

    int bytes = Math.Abs(bmpData.Stride) * objBmpImage.Height;
    byte[] rgbValues = new byte[bytes];

    System.Runtime.InteropServices.Marshal.Copy(ptr, rgbValues, 0, bytes);

    int counter = 0;
    int counterdeluxe = 0;
    BitArray bitarray = new BitArray(8);

    Random r = new Random();

    Boolean last = true;
    for (int i = 0; i < 225 / 8; i++)
    {
        rgbValues[i] = (byte)r.Next(255);
    }

    System.Runtime.InteropServices.Marshal.Copy(rgbValues, 0, ptr, bytes);


    objBmpImage.UnlockBits(bmpData);

    return (objBmpImage);
}

Хотя по какой-то причине он создает только половину изображения: http://dl.dropbox.com/u/1814002/maze.png

Edit4: Ах, кажется, что биты по ширине всегда округляются до 4-байтового числа. Теперь это начинает иметь смысл для меня:).

Edit5: Хорошо, это больше не имеет смысла, лол, я пока останусь с графикой, наверное,

Edit6: Я не мог отпустить это, поэтому я посмотрел на это снова и обнаружил следующее: В тот момент, когда я использую BitArray, чтобы преобразовать свои отдельные биты в байт, который я затем записываю в ImageData, что-то идет не так, по-видимому, битовый массив должен был записываться в обратном порядке. Наконец-то теперь все работает правильно:).

Все проблемы решены, и мой генератор лабиринта запущен и работает. Спасибо всем:)

1 Ответ

3 голосов
/ 18 января 2012

Если ваши лабиринты просто черно-белые, вы можете попробовать:

Bitmap bitmap = new Bitmap(16000, 16000, PixelFormat.Format1bppIndexed);

Предполагается, что оно сохраняет изображение в этом формате в памяти, что должно быть значительно более эффективным, чем формат пикселей по умолчанию.

На моем компьютере (который имеет 12 ГБ памяти, по общему признанию) 16000x16000 работает по умолчанию, а 32000x32000 - нет. Даже 32000x32000 работает с Format1bppIndexed.

РЕДАКТИРОВАТЬ: Как отмечено в комментариях, вы должны использовать using операторов для растровых изображений:

using (Bitmap bitmap = ...)
{
}

... чтобы их можно было почистить надлежащим образом.

...