子图的分割,子图依据图片中的透明区域自行分割

        //=======================================================
        // 子图的分割,子图依据图片中的透明区域自行分割
        //=======================================================

        /// <summary>
        /// 对图像pic进行图块分割,分割为一个个的矩形子图块区域
        /// 分割原理: 相邻的连续区域构成一个图块,透明区域为分割点
        /// </summary>
        public Rectangle[] GetRects(Bitmap pic)
        {
            List<Rectangle> Rects = new List<Rectangle>();
            Rectangle rect;

            bool[][] Colors = getColors(pic);           //获取图像对应的非透明像素点

            for (int i = 0; i < pic.Height; i++)
            {
                for (int j = 0; j < pic.Width; j++)
                {
                    if (Exist(Colors, i, j))
                    {
                        rect = GetRect(Colors, i, j);   //获取非透明像素点所在的矩形区域

                        if (rect.Width > 10 && rect.Height > 10)    //剔除尺寸小于10x10的子图区域
                            Rects.Add(rect);            //记录区域范围
                    }
                }
            }

            return Rects.ToArray();
        }

        //获取图像buildPic的所有子图区域的图像
        private Bitmap[] getSubPics(Image buildPic, Rectangle[] buildRects)
        {
            //创建建筑块图像
            Bitmap[] buildTiles = new Bitmap[buildRects.Length];
            for (int i = 0; i < buildRects.Length; i++)
            {
                buildTiles[i] = GetRect(buildPic, buildRects[i]);     //获取建筑块的图像
            }

            return buildTiles;
        }

        //判断所有像素点是否存在非透明像素
        public bool[][] getColors(Bitmap pic)
        {
            Color C;
            bool[][] has = new bool[pic.Height][];
            int count;

            for (int i = 0; i < pic.Height; i++)
            {
                has[i] = new bool[pic.Width];
                for (int j = 0; j < pic.Width; j++)
                {
                    C = pic.GetPixel(j, i);

                    //统计RGB值近似为0的数目
                    count = 0;
                    if(C.R < 4) count++;
                    if (C.G < 4) count++;
                    if (C.B < 4) count++;

                    //若透明度近似为0,视为透明像素。或RGB中有两个值近似为0且透明度很小,也视为透明像素。
                    if (C.A < 3 || (count >= 2 && C.A < 30)) has[i][j] = false;
                    else has[i][j] = true;
                }
            }

            return has;
        }

        //判断坐标处是否存在非透明像素值
        public bool Exist(bool[][] Colors, int x, int y)
        {
            if (x < 0 || y < 0 || x >= Colors.Length || y >= Colors[0].Length) return false;
            else return Colors[x][y];
        }

        //判定区域Rect右侧是否存在像素点
        public bool R_Exist(bool[][] Colors, Rectangle Rect)
        {
            if (Rect.Right >= Colors[0].Length || Rect.Left < 0) return false;
            for (int i = 0; i < Rect.Height; i++)
                if (Exist(Colors, Rect.Top + i, Rect.Right + 1)) return true;
            return false;
        }
        public bool D_Exist(bool[][] Colors, Rectangle Rect)
        {
            if (Rect.Bottom >= Colors.Length || Rect.Top < 0) return false;
            for (int i = 0; i < Rect.Width; i++)
                if (Exist(Colors, Rect.Bottom + 1, Rect.Left + i)) return true;
            return false;
        }
        public bool L_Exist(bool[][] Colors, Rectangle Rect)
        {
            if (Rect.Right >= Colors[0].Length || Rect.Left < 0) return false;
            for (int i = 0; i < Rect.Height; i++)
                if (Exist(Colors, Rect.Top + i, Rect.Left - 1)) return true;
            return false;
        }
        public bool U_Exist(bool[][] Colors, Rectangle Rect)
        {
            if (Rect.Bottom >= Colors.Length || Rect.Top < 0) return false;
            for (int i = 0; i < Rect.Width; i++)
                if (Exist(Colors, Rect.Top - 1, Rect.Left + i)) return true;
            return false;
        }

        //获取坐标所在图块的区域范围
        public Rectangle GetRect0(bool[][] Colors, int x, int y)
        {
            Rectangle Rect = new Rectangle(new Point(y, x), new Size(1, 1));   //创建所在区域

            bool flag;
            do
            {
                flag = false;

                while (R_Exist(Colors, Rect)) { Rect.Width++; flag = true; }
                while (D_Exist(Colors, Rect)) { Rect.Height++; flag = true; }
                while (L_Exist(Colors, Rect)) { Rect.Width++; Rect.X--; flag = true; }
                while (U_Exist(Colors, Rect)) { Rect.Height++; Rect.Y--; flag = true; }
            }
            while (flag == true);

            区域范围放大1个像素
            if (Rect.X > 0) { Rect.X--; Rect.Width++; }
            if (Rect.Y > 0) { Rect.Y--; Rect.Height++; }
            if (Rect.X + Rect.Width + 1 < Colors[0].Length) { Rect.Width++; }
            if (Rect.Y + Rect.Height + 1 < Colors.Length) { Rect.Height++; }

            //区域范围放大1个像素
            if (Rect.X > 0) { Rect.X--; Rect.Width++; }
            if (Rect.Y > 0) { Rect.Y--; Rect.Height++; }
            if (Rect.X + Rect.Width + 1 < Colors[0].Length) { Rect.Width++; }
            if (Rect.Y + Rect.Height + 1 < Colors.Length) { Rect.Height++; }

            //Rect = expend2pix(Colors, Rect);    //区域范围扩大2个像素
            clearRect(Colors, Rect);            //清空已选择的区域

            return Rect;
        }

        //获取坐标所在图块的区域范围
        public Rectangle GetRect(bool[][] Colors, int x, int y)
        {
            Rectangle Rect = new Rectangle(new Point(y, x), new Size(1, 1));   //创建所在区域

            bool flag;
            do
            {
                flag = false;

                while (R_Exist(Colors, Rect)) { Rect.Width++; flag = true; }
                while (D_Exist(Colors, Rect)) { Rect.Height++; flag = true; }
                while (L_Exist(Colors, Rect)) { Rect.Width++; Rect.X--; flag = true; }
                while (U_Exist(Colors, Rect)) { Rect.Height++; Rect.Y--; flag = true; }
            }
            while (flag == true);

            clearRect(Colors, Rect);            //清空已选择的区域

            Rect.Width++;
            Rect.Height++;

            return Rect;
        }

        //清空区域内的像素非透明标记
        public void clearRect(bool[][] Colors, Rectangle Rect)
        {
            for (int i = Rect.Top; i <= Rect.Bottom; i++)
                for (int j = Rect.Left; j <= Rect.Right; j++)
                    Colors[i][j] = false;
        }
        /// <summary>
        /// 从图像pic中截取区域Rect构建新的图像
        /// </summary>
        public Bitmap GetRect(Image pic, Rectangle Rect)
        {
            //创建图像
            Rectangle drawRect = new Rectangle(0, 0, Rect.Width, Rect.Height);  //绘制整块区域
            Bitmap tmp = new Bitmap(drawRect.Width, drawRect.Height);           //按指定大小创建位图

            //绘制
            Graphics g = Graphics.FromImage(tmp);                   //从位图创建Graphics对象
            g.Clear(Color.FromArgb(0, 0, 0, 0));                    //清空
            g.DrawImage(pic, drawRect, Rect, GraphicsUnit.Pixel);   //从pic的给定区域进行绘制

            return tmp;     //返回构建的新图像
        }


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值