在C#中裁剪图像空白处

4

我有一个请求,需要在C#中裁剪图像的空白部分。我从论坛上搜寻了一些方法,但都不能满足我的需求。

这是原始图像:

enter image description here

以下是我期望得到的结果:

enter image description here

非常感谢任何帮助。


1
测量每一侧可以深入多少,以便您拥有一条不间断的白色像素线。 - spender
请查看此链接,了解有关图像调整大小和裁剪的信息。它可能会有所帮助:http://jasonjano.wordpress.com/2010/02/13/image-resizing-and-cropping-in-c/ - Carlos Landeras
查找您顶部、底部、左侧和右侧黑点的坐标,并裁剪矩形,例如https://dev59.com/7XRB5IYBdhLWcg3wEDql。 - Alex
2个回答

11

您可以尝试获取第一张图片的数据(有一张图片),并将数据绘制到新的图片中。尝试这种方法。希望能对您有所帮助。

private static Bitmap ImageTrim(Bitmap img)
{
    //get image data
    BitmapData bd= img.LockBits(new Rectangle(Point.Empty, img.Size),
    ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
    int[] rgbValues = new int[img.Height * img.Width];
    Marshal.Copy(bd.Scan0, rgbValues, 0, rgbValues.Length);
    img.UnlockBits(bd);


    #region determine bounds
    int left = bd.Width;
    int top = bd.Height;
    int right = 0;
    int bottom = 0;

    //determine top
    for (int i = 0; i < rgbValues.Length; i++)
    {
        int color = rgbValues[i] & 0xffffff;
        if (color != 0xffffff)
        {
            int r = i / bd.Width;
            int c = i % bd.Width;

            if (left > c)
            {
                left = c;
            }
            if (right < c)
            {
                right = c;
            }
            bottom = r;
            top = r;
            break;
        }
    }

    //determine bottom
    for (int i = rgbValues.Length - 1; i >= 0; i--)
    {
        int color = rgbValues[i] & 0xffffff;
        if (color != 0xffffff)
        {
            int r = i / bd.Width;
            int c = i % bd.Width;

            if (left > c)
            {
                left = c;
            }
            if (right < c)
            {
                right = c;
            }
            bottom = r;
            break;
        }
    }

    if (bottom > top)
    {
        for (int r = top + 1; r < bottom; r++)
        {
            //determine left
            for (int c = 0; c < left; c++)
            {
                int color = rgbValues[r * bd.Width + c] & 0xffffff;
                if (color != 0xffffff)
                {
                    if (left > c)
                    {
                        left = c;
                        break;
                    }
                }
            }

            //determine right
            for (int c = bd.Width - 1; c > right; c--)
            {
                int color = rgbValues[r * bd.Width + c] & 0xffffff;
                if (color != 0xffffff)
                {
                    if (right < c)
                    {
                        right = c;
                        break;
                    }
                }
            }
        }
    }

    int width = right - left + 1;
    int height = bottom - top + 1;
    #endregion

    //copy image data
    int[] imgData = new int[width * height];
    for (int r = top; r <= bottom; r++)
    {
        Array.Copy(rgbValues, r * bd.Width + left, imgData, (r - top) * width, width);
    }

    //create new image
    Bitmap newImage = new Bitmap(width, height, PixelFormat.Format32bppArgb);
    BitmapData nbd
        = newImage.LockBits(new Rectangle(0, 0, width, height),
            ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);
    Marshal.Copy(imgData, 0, nbd.Scan0, imgData.Length);
    newImage.UnlockBits(nbd);

    return newImage;
}            

3

如果您的图像只有2种颜色(白色和黑色),则可以遍历图像并找到左上角像素集和右下角像素集,然后可以剪裁它:

(伪代码,取决于您用什么来获取图像像素)

int minX = int.MaxValue, maxX = 0, minY = int.MaxValue, maxY = 0;
for (x = 0; x < image.Width, x++)
{
    for (y = 0; y < image.Height; y++)
    {
        if (image[x, y] == 1)
        {
            if (x < minX) minX = x;
            else if (x > maxX) maxX = x;
            if (y < minY) minY = y;
            else if (y > maxY) maxY = y;
        }
    }
}

那么你将拥有坐标,从而能够裁剪图像

我相信这可以进行优化,但这是一般的想法


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接