• C#实现自动切割图片


    由于做一个TD游戏需要一些图片素材,可是现有的从网上下载的<保卫萝卜>的图片资源是多张图片合在一起的,并且没有什么规则,虽然有 个xml文件似乎用来描述此图片内子图片位置大小等信息,但由于不想花太多时间在研究这个xml文件内容上,所以转变思路想写一个根据透明的边界自动分割 图片的工具.

    实现了,基本满足需要.

    主界面:

    Qie()是开始切图第一个函数,遍历图片每个像素,找到不是透明的就开始切图.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    void Qie()
        {
           
            for (int x = 0; x < bmp.Width; x++)
            {
                for (int y = 0; y < bmp.Height; y++)
                {
                    if (isT(x,y ))
                    {
     
                    }
                    else
                    {
                        int maxY = 0, maxX = 0, minX = 9999, minY = 9999;
                        StartQie(x,y,ref minX,ref maxX,ref minY,ref maxY);
                        if (maxY != 0)
                        {
                            JianQie(minX, maxX, minY, maxY);
                        }
                    }
                }
            }
        }

     StartQie是一个递归函数,目的查找与当前像素相连并且非透明的像素,判断她的位置是否比当前的范围要大,是则更新当前最大范围.

    最后切割图片的大小就是最大范围的大小.

    复制代码
        void StartQie(int x2, int y2 , ref int minX,ref int maxX, ref int minY,ref int maxY)
            {
                List<Point> ps = new List<Point>();
                Find(x2, y2,ref ps);
    
                foreach (var a in ps)
                {
                    if (a.X < minX) minX = a.X;
                    if (a.Y < minY) minY = a.Y;
                    if (a.X > maxX) maxX = a.X;
                    if (a.Y > maxY) maxY = a.Y;
                }
                //return;
                for (int x = minX; x <= maxX; x++)
                {
                    for (int y = minY; y <=maxY; y++)
                    {
                        if (Conten(ps, x, y)) continue;
                        if (isT(x, y) == false)
                        {
                            StartQie(x2, y2, ref minX, ref maxX, ref minY, ref maxY);
                        }
                    }
                }
    
            }
    复制代码
    复制代码
      //这个函数用来切割图片,根据给定范围,从母图上切出子图并保存本地.

    void JianQie(int minX, int maxX,int minY, int maxY) { i++; var w = maxX - minX; var h = maxY - minY; var img = new Bitmap(w,h); Graphics g = Graphics.FromImage(img); g.PageUnit = GraphicsUnit.Pixel; g.DrawImage(bmp, new RectangleF(0, 0, w, h), new RectangleF(minX, minY, w, h), GraphicsUnit.Pixel); img.Save(bp+"/"+ i + ".png", System.Drawing.Imaging.ImageFormat.Png); for (int x = minX; x <= maxX; x++) { for (int y = minY; y <= maxY; y++) { bmp.SetPixel(x,y,Color.Transparent); } } }
    复制代码

    这是最后一个比较重要的函数,定义8个方向,Find方法用于根据8个方向查找相连且不透明的像素,找到就加入List中.

    复制代码
      int[,] csz = new int[8, 2] { { 0, 1 }, { 0, -1 }, { -1, 0 }, { 1, 0 }, { 1, 1 }, { 1, -1 }, { -1, -1 }, { -1, 1 } };
          
            void Find(int x,int y ,ref List<Point> ps){
    
                for (int i = 0; i < 8; i++)
                {
                    int zy = csz[i, 0];
                    int sx = csz[i, 1];
                    var nx=x+1*zy;
                    var ny=y+1*sx;
                    if (Conten(ps,nx,ny)==false && nx > -1 && nx < bmp.Width && ny > -1 && ny < bmp.Height && isT(nx, ny)==false)
                    {
                        ps.Add(new Point(nx,ny));
                        Find(nx, ny ,ref ps);
                    }
                }
            }
    复制代码

    小软件,有时候却很有用.目前不足是:不能自动识别小元素,这个其实很好解决,但当时目的已经基本实现便没有多花时间来解决这个问题.

    切出来的图:

     
     
  • 相关阅读:
    安装PetShop后调试的诸多问题
    初学FF(火狐)的扩展(Extensions)
    发现JavaScript中Number的toFixed()四舍五入时的一个问题,请教大虾!(原来是浏览器问题)
    PHP哪用手工配置啊。。。哎。。真是的。
    新鸟文章:foreach里的Sqlcommand(有SqlTransaction)
    说下按位异或(^)和按位与(&)的一点知识(没技术含量的)
    How browers work?
    开篇:希望结交各位,共同学习进步!
    第01章 基础知识
    20060818网摘
  • 原文地址:https://www.cnblogs.com/webenh/p/16038947.html
Copyright © 2020-2023  润新知