С# из памяти при создании растрового изображения

Я создаю приложение (Windows Form), которое позволяет пользователю делать снимок экрана на основе выбранных им мест (перетаскивание для выбора области). Я хотел добавить небольшую "область предварительного просмотра", которая была увеличена, чтобы пользователь мог выбрать область, которую они хотят более точно (большие пиксели). В событии mousemove у меня есть следующий код...

private void falseDesktop_MouseMove(object sender, MouseEventArgs e)
    {
        zoomBox.Image = showZoomBox(e.Location);
        zoomBox.Invalidate();
        bmpCrop.Dispose();
    }

private Image showZoomBox(Point curLocation)
    {
        Point start = new Point(curLocation.X - 50, curLocation.Y - 50);
        Size size = new Size(100, 90);
        Rectangle rect = new Rectangle(start, size);
        Image selection = cropImage(falseDesktop.Image, rect);
        return selection;
    }

private static Bitmap bmpCrop;
private static Image cropImage(Image img, Rectangle cropArea)
    {
        if (cropArea.Width != 0 && cropArea.Height != 0)
        {
            Bitmap bmpImage = new Bitmap(img);
            bmpCrop = bmpImage.Clone(cropArea, bmpImage.PixelFormat);
            bmpImage.Dispose();
            return (Image)(bmpCrop);
        }
        return null;
    }

Линия, которая терпит неудачу и имеет исключение Out of Memory:

bmpCrop = bmpImage.Clone(cropArea, bmpImage.PixelFormat);

В основном, что это такое, требуется прямоугольник размером 100x90 вокруг указателя мыши и вытаскивает его в zoomBox, который является элементом управления фотокамерой. Однако при этом я получаю ошибку Out Of Memory. Что я здесь делаю неправильно?

Спасибо за вашу помощь.

Ответ 1

Недостаточно памяти при визуализации С#, обычно является признаком неправильного прямоугольника или точки - немного красной селедки. Уверен, что start имеет значение отрицательный X или Y при возникновении ошибки или размер .Hight + Y или Size.Width + X больше, чем высота или ширина изображения.

Ответ 2

MSDN объясняет, что OutOfMemoryException означает

rect находится за пределами растровых границ источника

где rect - первый параметр метода Bitmap.Clone.

Поэтому проверьте, что параметр cropArea не больше вашего изображения.

В GDI + an OutOfMemoryException не означает "вне памяти"; код ошибки GDI + OufOfMemory был перегружен, что означает разные вещи. Причины этого исторические и хорошо описаны Хансом Пассантом в другом ответе.

Ответ 3

Используйте объект Bitmap следующим образом:

using (Bitmap bmpImage = new Bitmap(img))
{
    // Do something with the Bitmap object
}

Ответ 4

вы должны проверить, больше ли curLocation.X больше 50, иначе ваш прямоугольник начнет в отрицательной области (и, конечно, curLocation.Y)

Ответ 5

Если окно масштабирования уходит с края области рабочего стола, то при попытке обрезки вы просите систему сделать новое изображение, которое содержит пиксели вне области видеопамяти. Не забудьте ограничить область масштабирования так, чтобы ни один из ее экстентов не был меньше нуля или больше краев экрана.

Ответ 6

Если вы создаете новые растровые изображения снова и снова, вам может потребоваться вызвать GC.Collect();, который заставит С# на сбор мусора