c#剪切图像中的非透明块

时间:2015-08-12 17:13:06

标签: c# winforms image-processing

假设我们有一个32BppARGB图像: enter image description here

我想裁剪每个块并将其保存为单独的transpert像素的分离图像!

到目前为止,这是我的代码:

  private unsafe Bitmap CodeImage(Bitmap bmp)
    {

        Bitmap bmpRes = new Bitmap(bmp.Width, bmp.Height);

        BitmapData bmData = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), System.Drawing.Imaging.ImageLockMode.ReadOnly, bmp.PixelFormat);


        IntPtr scan0 = bmData.Scan0;


        int stride = bmData.Stride;


        int nWidth = bmp.Width;
        int nHeight = bmp.Height;
        int minX = 10000 ;
        int minY = 1000;
        int width=0;
        var height= 0;

        bool found = false;
        for (int y = 0; y < nHeight; y++)
        {
            byte* p = (byte*)scan0.ToPointer();
            p += y * stride;


            for (int x = 0; x < nWidth; x++)
            {




                if (p[3] != 0)  //Check if pixel is transpert;
                {


                    found = true;
                    if (x < minX)
                        minX = x;
                    if (y < minY)
                        minY = y;
                    if (x > width)
                        width = x;
                    if (y > height)
                        height = y;


                }

                else

                {
                    if (found)
                    {
                        Rectangle temp = new Rectangle(minX, minY, width - minX, height-minY);
                        MessageBox.Show(temp.Top.ToString() + "," + temp.Left.ToString() +", "+ temp.Width.ToString()+", "+temp.Height.ToString());                            


                        return bmp.Clone(temp, bmp.PixelFormat);
                    }
                }



                p += 4;


            }
        }


        return null;

    }

正如你所看到我试图识别第一个蓝色块,例如,当像素不再透明时,块就结束了,我将矩形的尺寸存储在temp中。它的效果确实很好,对于这个图像它打印一个矩形,这个边界(200,800,399,0)几乎可以工作,但高度有一个问题......不知何故它的0和我不知道为什么......也许那里&#39; s是一个简单的类型,我无法弄清楚。 谢谢你的一切

1 个答案:

答案 0 :(得分:0)

正如我在评论中所说,你应扫描整个图像以获得正确的高度。您的代码仅扫描蓝色矩形的forst线。它没有进入第二行,因为它退出。对于蓝色矩形,代码应为:

private unsafe Bitmap CodeImage(Bitmap bmp)
{

    Bitmap bmpRes = new Bitmap(bmp.Width, bmp.Height);

    BitmapData bmData = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), System.Drawing.Imaging.ImageLockMode.ReadOnly, bmp.PixelFormat);


    IntPtr scan0 = bmData.Scan0;


    int stride = bmData.Stride;


    int nWidth = bmp.Width;
    int nHeight = bmp.Height;
    int minX = 10000 ;
    int minY = 1000;
    int width=0;
    var height= 0;

    bool found = false;
    for (int y = 0; y < nHeight; y++)
    {
        byte* p = (byte*)scan0.ToPointer();
        p += y * stride;


        for (int x = 0; x < nWidth; x++)
        {

            if (p[0] == 255 && p[1] == 0 && p[2] == 0 && p[3] != 0)  //Check if pixel is blue;
            {


                found = true;
                if (x < minX)
                    minX = x;
                if (y < minY)
                    minY = y;
                if (x > width)
                    width = x;
                if (y > height)
                    height = y;


            }

            p += 4;


        }
    }

    if (found)
    {
        //add one for the width and height
        Rectangle temp = new Rectangle(minX, minY, width - minX + 1, height - minY + 1);
        MessageBox.Show(temp.Top.ToString() + "," + temp.Left.ToString() + ", " + temp.Width.ToString() + ", " + temp.Height.ToString());


        return bmp.Clone(temp, bmp.PixelFormat);
    }

    return null;

}

enter image description here

对于这个简单的例子(左上图),我们可以有4种不同的矩形组合。那么如果我们有更复杂的情况会发生什么?