4

我有在 C# 中裁剪图像空白的请求,我从论坛中搜索了一些方法,但它不能满足我的请求。

有原图,

在此处输入图像描述

这是我期望的结果,

在此处输入图像描述

任何帮助表示赞赏。

4

2 回答 2

10

您可以尝试获取第一个图像数据(有图像),并将数据绘制到新图像中。试试这个方法。希望它可以帮助你。

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;
}            
于 2013-05-16T09:46:20.050 回答
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;
        }
    }
}

然后您将获得可让您裁剪图像的坐标

我确信这可以优化,但这是一般的想法

于 2013-05-16T09:36:01.373 回答