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);
                }
            }
        }
復制代碼

小軟件,有時候卻很有用.目前不足是:不能自動識別小元素,這個其實很好解決,但當時目的已經基本實現便沒有多花時間來解決這個問題.

切出來的圖:

 

 
 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM