C# автоматически обрезать изображение

У меня есть черно-белое изображение System.Drawing.Bitmap. Мне нужно автоматически обрезать его, чтобы оно было настолько большим, насколько это необходимо для изображения. Это изображение всегда начинается с верхней левой (0,0) позиции, но я не уверен, сколько высоты и ширины потребуется. Есть ли способ автоматически обрезать его по размеру?


person Justin808    schedule 11.08.2011    source источник
comment
Что изображение содержит в пустой области? белые или прозрачные пиксели?   -  person Gilad Naaman    schedule 12.08.2011
comment
Ммм ... Я не знаю, насколько это эффективно, но я бы искал последнюю строку пикселей, которая полностью белая (или первая из последних), и получил бы ее номер. То же самое для столбца.   -  person Gilad Naaman    schedule 12.08.2011


Ответы (2)


Ниже приведен код, который я использовал:

    // Figure out the final size
    int maxX = 0;
    int maxY = 0;
    for (int x = 0; x < bitmap.Width; x++)
    {
        for (int y = 0; y < bitmap.Height; y++)
        {
            System.Drawing.Color c = bitmap.GetPixel(x, y);
            System.Drawing.Color w = System.Drawing.Color.White;
            if (c.R != w.R || c.G != w.G || c.B != w.B)
            {
                if (x > maxX)
                    maxX = x;
                if (y > maxY)
                    maxY = y;
            }
        }
    }
    maxX += 2;
person Justin808    schedule 16.08.2011
comment
Я не знаю никаких данных о ваших изображениях, но кажется, что вы можете ускорить процесс, разделив изображение пополам, проверив любые небелые значения, которые подскажут вам, какую половину разделить пополам... и так далее. Возможно, вам удастся достичь O((log h)*(log w)) наихудшего времени вместо O(w*h). - person Kaleb Pederson; 16.08.2011
comment
Я предполагаю, что это сработает для закрытых фигур, но, вероятно, не для изображения, содержащего только два непустых пикселя. Ну что ж, стоит учитывать в зависимости от изображения. - person Kaleb Pederson; 16.08.2011

Если ваше изображение не начинается с 0,0, как у меня, вот вариант, который дает вам границы автоматической обрезки:

public static Rectangle GetAutoCropBounds(Bitmap bitmap)
{
    int maxX = 0;
    int maxY = 0;

    int minX = bitmap.Width;
    int minY = bitmap.Height;

    for (int x = 0; x < bitmap.Width; x++)
    {
        for (int y = 0; y < bitmap.Height; y++)
        {
            var c = bitmap.GetPixel(x, y);
            var w = Color.White;
            if (c.R != w.R || c.G != w.G || c.B != w.B)
            {
                if (x > maxX)
                    maxX = x;
                if (x < minX)
                    minX = x;
                if (y > maxY)
                    maxY = y;
                if (y < minY)
                    minY = y;
            }
        }
    }

    maxX += 2;

    return new Rectangle(minX, minY, maxX - minX, maxY - minY);
}

Примечание: если вы обрабатываете любое количество изображений в большом количестве или с высоким разрешением, вам следует изучить более быстрые альтернативы, чем метод GetPixel.

person test    schedule 17.06.2021