【问题标题】:C# Bitmap difficultiesC#位图困难
【发布时间】:2012-01-25 16:00:20
【问题描述】:

我要做的是检查图像行或列,如果它包含所有白色像素,则修剪该行或列。 我不知道为什么,但是当我运行此代码 sn-p 时,TrimLeft 中的 img.Width 为 1,然后从中减去 1。 实际图像宽度为 175。我最终得到一个 ArgumentException。我有一个类似的修剪右侧的方法,效果很好。

class ImageHandler
{

    public Bitmap img;
    public List<int[]> pixels = new List<int[]>();

    public ImageHandler(String path)
    {
        img = new Bitmap(path);
        GetPixels();
    }

    public void TrimLeft()
    {
        while (CheckColIfWhite(0, 0))
        {
            Rectangle cropBox = new Rectangle(1, 0, (img.Width-1), img.Height);
            Bitmap cropdImg = CropImage(img, cropBox);
            img = cropdImg;
        }
    }

    public bool CheckColIfWhite(int colx, int starty)
    {
        bool allPixelsWhite = false;
        int whitePixels = 0;

        for (int y = starty; y < img.Height; y++)
        {
            if (pixels[y][colx] >= 200) { whitePixels++; }
            else { return false; }
            if (whitePixels == img.Height) { allPixelsWhite = true; }
        }
        return allPixelsWhite;
    }

    public void GetPixels()
    {
        for (int y = 0; y < img.Height; y++)
        {
            int[] line = new int[img.Width];
            for (int x = 0; x < img.Width; x++)
            {
                line[x] = (int) img.GetPixel(x, y).R;
            }
            pixels.Add(line);
        }
    }

    public Bitmap CropImage(Bitmap tImg, Rectangle area) 
    {
        Bitmap bmp = new Bitmap(tImg);
        Bitmap bmpCrop = bmp.Clone(area, bmp.PixelFormat);
        return bmpCrop;
    }
}

【问题讨论】:

    标签: c# bitmap


    【解决方案1】:

    您的方法似乎效率非常低 - 如果图像是 175 像素宽且全白,您将创建 175 个副本,在尝试创建 0 像素宽图像之前(可能)失败.

    为什么不依次检查每一列,直到找到非白色列,然后在那时执行单次裁剪。未经测试的代码,以及其他明显的变化:

    public Bitmap CropImage (Bitmap image)
    {
        int top = 0;
        int bottom = image.Height-1;
        int left = 0;
        int right = image.Width-1;
        while(left < right && CheckColIfWhite(image,left))
             left++;
        if(left==right) return null; //Entirely white
        while(CheckColIfWhite(image,right)) //Because left stopped, we know right will also
             right--;
        while(CheckRowIfWhite(image,top))
             top++;
        while(CheckRowIfWhite(image,bottom))
             bottom--;
        return CropImage(image,new Rectangle(left,top,right-left+1,bottom-top+1));
    }
    

    (例如,我现在正在传递图像,我已修改 CheckColIfWhiteCheckRowIfWhite 以获取图像,并假设一个参数始终固定为 0)


    另外,不知道你为什么要事先提取像素数组,所以我把我重写的CheckColIfWhite 也放了:

    public bool CheckColIfWhite(Bitmap image,int colx)
    {
        for (int y = 0; y < image.Height; y++)
        {
            if (image.GetPixel(colx,y).R < 200)
                return false;
        }
        return true;
    }
    

    【讨论】:

    • 这很有帮助,谢谢。我知道我的方法效率低下,只是没有找到更好的方法。我最初从图像中抓取所有像素以从文件的多次读取中保存。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-11
    相关资源
    最近更新 更多