c# 9png实现(图片缩放)

跟据9png的实现原理自己写了个生成图片的函数,9png的原理是将图片切成9块如下

其中1、3、7、9不进行缩放,2,4,5,6,8进行缩放,这样就防止了放大后导致边界出现锯齿的问题

在实现过程中主要的就是找到4个关键点,如下

然后根据p1,p2,p3,p4将原图画到新大小的图上

具体代码如下

获得关键点

/// <summary>
        /// 获取4个关键坐标点左边1,2  上边1,2
        /// </summary>
        /// <param name="bitmap">图片</param>
        /// <param name="backColor">背景色</param>
        /// <param name="intAalpha">透明度</param>
        /// <returns>0:左1 1:左2 2:上1 3:上2</returns>
        private Point[] GetIndex(Bitmap bitmap, Color? backColor = null, int intAalpha = 0)
        {
            int intTop = 0;
            int intRight = 0;
            int intBottom = 0;
            int intLeft = 0;

            Point ptop1 = Point.Empty, ptop2 = Point.Empty;
            Point pleft1 = Point.Empty, pleft2 = Point.Empty;
            Point pbottom1 = Point.Empty, pbottom2 = Point.Empty;
            Point pright1 = Point.Empty, pright2 = Point.Empty;
            #region 边界
            //left
            for (int x = 0; x < bitmap.Width; x++)
            {
                for (int y = 0; y < bitmap.Height; y++)
                {
                    Color c = bitmap.GetPixel(x, y);
                    if (c.A <= intAalpha)
                        continue;
                    if (backColor.HasValue && c.ToArgb() == backColor.Value.ToArgb())
                    {
                        continue;
                    }
                    intLeft = x;
                    x = int.MaxValue - 10;
                    break;
                }
            }

            //right
            for (int x = bitmap.Width - 1; x >= 0; x--)
            {
                for (int y = 0; y < bitmap.Height; y++)
                {
                    Color c = bitmap.GetPixel(x, y);
                    if (c.A <= intAalpha)
                        continue;
                    if (backColor.HasValue && c.ToArgb() == backColor.Value.ToArgb())
                    {
                        continue;
                    }
                    intRight = x;
                    x = -10;
                    break;
                }
            }

            //top
            for (int y = 0; y < bitmap.Height; y++)
            {
                for (int x = 0; x < bitmap.Width; x++)
                {
                    Color c = bitmap.GetPixel(x, y);
                    if (c.A <= intAalpha)
                        continue;
                    if (backColor.HasValue && c.ToArgb() == backColor.Value.ToArgb())
                    {
                        continue;
                    }
                    intTop = y;
                    y = int.MaxValue - 10;
                    break;
                }
            }

            //bottom
            for (int y = bitmap.Height - 1; y >= 0; y--)
            {
                for (int x = 0; x < bitmap.Width; x++)
                {
                    Color c = bitmap.GetPixel(x, y);
                    if (c.A <= intAalpha)
                        continue;
                    if (backColor.HasValue && c.ToArgb() == backColor.Value.ToArgb())
                    {
                        continue;
                    }
                    intBottom = y;
                    y = -10;
                    break;
                }
            }
            #endregion

            #region 顶点
            bool blnGet1 = false;
            bool blnGet2 = false;
            //上1  下1
            for (int x = 0; x < bitmap.Width; x++)
            {
                //上1
                if (!blnGet1)
                {
                    Color c = bitmap.GetPixel(x, intTop);
                    if (c.A <= intAalpha)
                        continue;
                    if (backColor.HasValue && c.ToArgb() == backColor.Value.ToArgb())
                    {
                        continue;
                    }
                    ptop1 = new Point(x, intTop);
                    blnGet1 = true;
                }
                //下1
                if (!blnGet2)
                {
                    Color c = bitmap.GetPixel(x, intBottom);
                    if (c.A <= intAalpha)
                        continue;
                    if (backColor.HasValue && c.ToArgb() == backColor.Value.ToArgb())
                    {
                        continue;
                    }
                    pbottom1 = new Point(x, intBottom);
                    blnGet2 = true;
                }
                if (blnGet1 && blnGet2)
                {
                    break;
                }
            }

            blnGet1 = false;
            blnGet2 = false;
            //上2 下2
            for (int x = bitmap.Width - 1; x >= 0; x--)
            {
                //上2
                if (!blnGet1)
                {
                    Color c = bitmap.GetPixel(x, intTop);
                    if (c.A <= intAalpha)
                        continue;
                    if (backColor.HasValue && c.ToArgb() == backColor.Value.ToArgb())
                    {
                        continue;
                    }
                    ptop2 = new Point(x, intTop);
                    blnGet1 = true;
                }
                //下2
                if (!blnGet2)
                {
                    Color c = bitmap.GetPixel(x, intBottom);
                    if (c.A <= intAalpha)
                        continue;
                    if (backColor.HasValue && c.ToArgb() == backColor.Value.ToArgb())
                    {
                        continue;
                    }
                    pbottom2 = new Point(x, intBottom);
                    blnGet2 = true;
                }
                if (blnGet1 && blnGet2)
                {
                    break;
                }
            }

            blnGet1 = false;
            blnGet2 = false;
            //左1 右1
            for (int y = 0; y < bitmap.Height; y++)
            {
                //左1
                if (!blnGet1)
                {
                    Color c = bitmap.GetPixel(intLeft, y);
                    if (c.A <= intAalpha)
                        continue;
                    if (backColor.HasValue && c.ToArgb() == backColor.Value.ToArgb())
                    {
                        continue;
                    }
                    pleft1 = new Point(intLeft, y);
                    blnGet1 = true;
                }
                //右1
                if (!blnGet2)
                {
                    Color c = bitmap.GetPixel(intRight, y);
                    if (c.A <= intAalpha)
                        continue;
                    if (backColor.HasValue && c.ToArgb() == backColor.Value.ToArgb())
                    {
                        continue;
                    }
                    pright1 = new Point(intRight, y);
                    blnGet2 = true;
                }
                if (blnGet1 && blnGet2)
                {
                    break;
                }
            }

            blnGet1 = false;
            blnGet2 = false;
            //左2 右2
            for (int y = bitmap.Height - 1; y >= 0; y--)
            {
                //左2
                if (!blnGet1)
                {
                    Color c = bitmap.GetPixel(intLeft, y);
                    if (c.A <= intAalpha)
                        continue;
                    if (backColor.HasValue && c.ToArgb() == backColor.Value.ToArgb())
                    {
                        continue;
                    }
                    pleft2 = new Point(intLeft, y);
                    blnGet1 = true;
                }
                //右2
                if (!blnGet2)
                {
                    Color c = bitmap.GetPixel(intRight, y);
                    if (c.A <= intAalpha)
                        continue;
                    if (backColor.HasValue && c.ToArgb() == backColor.Value.ToArgb())
                    {
                        continue;
                    }
                    pright2 = new Point(intRight, y);
                    blnGet2 = true;
                }
                if (blnGet1 && blnGet2)
                {
                    break;
                }
            }
            #endregion

            Point pRleft1, pRleft2;
            Point pRtop1, pRtop2;
            int intLeftMax = Math.Max(ptop1.X, pbottom1.X);
            int intRightMin = Math.Min(ptop2.X, pbottom2.X);
            int intTopMax = Math.Max(pleft1.Y, pright1.Y);
            int intBottomMin = Math.Min(pleft2.Y, pright2.Y);

            if (intRightMin - intLeftMax ==0)
            {
                intRightMin = intRightMin + 1;
            }
            else if (intRightMin - intLeftMax > 4)
            {
                intRightMin = intRightMin - 2;
                intLeftMax = intLeftMax + 2;
            }

            if (intBottomMin - intTopMax == 0)
            {
                intBottomMin = intBottomMin + 1;
            }
            else if (intBottomMin - intTopMax > 4)
            {
                intBottomMin = intBottomMin - 2;
                intTopMax = intTopMax + 2;
            }

            pRleft1 = new Point(intLeft, intTopMax);
            pRleft2 = new Point(intLeft, intBottomMin);
            pRtop1 = new Point(intLeftMax, intTop);
            pRtop2 = new Point(intRightMin, intTop);
            Point[] ps = new Point[4];
            ps[0] = pRleft1;
            ps[1] = pRleft2;
            ps[2] = pRtop1;
            ps[3] = ptop2;
            return ps;
        }
View Code

画图

 private Bitmap CreateBitmap(Bitmap bitmap, Point[] ps, Size size)
        {
            Bitmap _returnBitmap = new Bitmap(size.Width, size.Height);
            Graphics g = Graphics.FromImage(_returnBitmap);
            //左上角  
            Rectangle destRect = new Rectangle(new Point(0, 0), new Size(ps[2].X, ps[0].Y));
            g.DrawImage(bitmap, destRect, 0, 0, ps[2].X, ps[0].Y, GraphicsUnit.Pixel);
            //右上角
            destRect = new Rectangle(new Point(size.Width - (bitmap.Width - ps[3].X), ps[3].Y), new Size(bitmap.Width - ps[3].X, ps[0].Y));
            g.DrawImage(bitmap, destRect, ps[3].X, ps[3].Y, bitmap.Width - ps[3].X, ps[0].Y, GraphicsUnit.Pixel);
            //左下角
            destRect = new Rectangle(new Point(0, size.Height - (bitmap.Height - ps[1].Y)), new Size(ps[2].X, bitmap.Height - ps[1].Y));
            g.DrawImage(bitmap, destRect, 0, ps[1].Y, ps[2].X, (bitmap.Height - ps[1].Y), GraphicsUnit.Pixel);
            //右下角
            destRect = new Rectangle(new Point(size.Width - (bitmap.Width - ps[3].X), size.Height - (bitmap.Height - ps[1].Y)), new Size(bitmap.Width - ps[3].X, bitmap.Height - ps[1].Y));
            g.DrawImage(bitmap, destRect, ps[3].X, ps[1].Y, bitmap.Width - ps[3].X, bitmap.Height - ps[1].Y, GraphicsUnit.Pixel);
            //上中
            destRect = new Rectangle(new Point(ps[2].X, 0), new Size(size.Width - ps[2].X - (bitmap.Width - ps[3].X), ps[0].Y));
            g.DrawImage(bitmap, destRect, ps[2].X, 0, ps[3].X - ps[2].X, ps[0].Y, GraphicsUnit.Pixel);
            //下中
            destRect = new Rectangle(new Point(ps[2].X, size.Height - (bitmap.Height - ps[1].Y)), new Size(size.Width - ps[2].X - (bitmap.Width - ps[3].X), bitmap.Height - ps[1].Y));
            g.DrawImage(bitmap, destRect, ps[2].X, ps[1].Y, ps[3].X - ps[2].X, bitmap.Height - ps[1].Y, GraphicsUnit.Pixel);
            //左中
            destRect = new Rectangle(new Point(0, ps[0].Y), new Size(ps[2].X, size.Height - ps[0].Y - (bitmap.Height - ps[1].Y)));
            g.DrawImage(bitmap, destRect, 0, ps[0].Y, ps[2].X, ps[1].Y-ps[0].Y, GraphicsUnit.Pixel);
            //右中
            destRect = new Rectangle(new Point(size.Width - (bitmap.Width - ps[3].X), ps[0].Y), new Size(bitmap.Width - ps[3].X, size.Height - ps[0].Y - (bitmap.Height - ps[1].Y)));
            g.DrawImage(bitmap, destRect, ps[3].X, ps[0].Y, bitmap.Width-ps[3].X, ps[1].Y - ps[0].Y, GraphicsUnit.Pixel);
            //中中
            destRect = new Rectangle(new Point(ps[2].X, ps[0].Y), new Size(size.Width - ps[2].X - (bitmap.Width - ps[3].X), size.Height - ps[0].Y - (bitmap.Height - ps[1].Y)));
            g.DrawImage(bitmap, destRect, ps[2].X, ps[0].Y, ps[3].X - ps[2].X, ps[1].Y - ps[0].Y, GraphicsUnit.Pixel);
            g.Dispose();
            return _returnBitmap;
        }
View Code

使用

 string strPath = @"D:\work-hzh\code\cy_hcmzc_v10\Km.PosZC\Km.PosZC\Resources\internet+.png";
            Bitmap bitmap = new Bitmap(strPath);
            Point[] ps = GetIndex(bitmap,Color.White);
            Bitmap br = CreateBitmap(bitmap, ps, new Size(400, 400));
            br.Save("d:\\123.png");
View Code

测试原图(100*100)

放大后(400*400)

这个是随便找的图,一般在应用中,是纯色活渐变色的会比较好,中间有图案的话 效果就不是太好了

posted @ 2018-06-15 14:06  冰封一夏  阅读(1208)  评论(0编辑  收藏  举报
HZHControls控件库官网:http://hzhcontrols.com