• 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-hzhcodecy_hcmzc_v10Km.PosZCKm.PosZCResourcesinternet+.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)

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

  • 相关阅读:
    T4 assembly
    HtmlPrefixScopeExtensions
    PetaPoco修改
    类属性赋值
    Microsoft Office 2007的ContentType
    年月日-正则
    Unity shader学习之逐顶点漫反射光照模型
    Unity3d之表情动画--眨眼
    shader之法线变换
    Unity之fragment shader中如何获得视口空间中的坐标
  • 原文地址:https://www.cnblogs.com/bfyx/p/9187046.html
Copyright © 2020-2023  润新知