Image processing with C# / Unity

Cause: There is a need to adjust the UI page size proportionally in batches. It's not a simple scaling, but all assets need to be scaled down. Therefore, the picture bears the brunt. Here is a record of the solution, because I have referred to a lot of other people's cases. Although they all describe the same, most of them only describe the method. Here is a record of the entire complete solution.

Environment: The requirement of Unity2019.4.10f1
is to reduce all pictures according to the ratio from 1080x2160 to 720x1440

Go directly to the code

 
  public static void ChangeImageSize()
    {
    
    
    	//获取需要处理的文件夹
        var oripath = Application.dataPath;
        string path = oripath.Substring(0, oripath.LastIndexOf("/", oripath.LastIndexOf("/") - 1)) +
                      "/art/UIProject/assets";
   
   		//获取文件夹下的所有文件	
        DirectoryInfo direction = new DirectoryInfo(path);
        //DirectoryInfo.GetFiles返回当前目录的文件列表   
        FileInfo[] files = direction.GetFiles("*", SearchOption.AllDirectories);


		//使用UNITY的进度条来显示处理进度
        var index = 0;
        EditorApplication.update = delegate()
        {
    
    
            bool isCancel =
                EditorUtility.DisplayCancelableProgressBar("处理中...", files[index].Name,
                    (float) index / files.Length);
        
        	//从所有文件中筛选出来图片资源
            if (!files[index].Name.EndsWith(".png") && !files[index].Name.EndsWith(".jpg"))
            {
    
    
                index++;
            }
            else
            {
    
    
                string xmlName = files[index].Name.Split('.')[0];
                
                //图片的处理方案
                var myBitmap = new System.Drawing.Bitmap(files[index].FullName);
                var x = Mathf.CeilToInt(myBitmap.Width * 720 / 1080f);
                var y = Mathf.CeilToInt(myBitmap.Height * 1440 / 2160f);
                var b = new System.Drawing.Bitmap(x, y);
                var g = System.Drawing.Graphics.FromImage(b);
                // 插值算法的质量 
                g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
                g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
                g.DrawImage(myBitmap, new System.Drawing.Rectangle(0, 0, x, y),
                    new System.Drawing.Rectangle(0, 0, myBitmap.Width, myBitmap.Height),
                    System.Drawing.GraphicsUnit.Pixel);
                g.Dispose();
                myBitmap.Dispose();
                //存到原图的位置
                b.Save(files[index].FullName);
                b.Dispose();

                index++;
            }
        
            if (isCancel || index >= files.Length)
            {
    
    
                EditorUtility.ClearProgressBar();
                EditorApplication.update = null;
                if (isCancel)
                {
    
    
                    EditorUtility.DisplayDialog("取消提示", "取消处理后需要把已处理的文件还原才能再次处理。", "确认");
                }
        
                if (index >= files.Length)
                {
    
    
                    EditorUtility.DisplayDialog("图片处理完成", "处理一次即可,如果误操作,需要把对应目录下所有图片文件还原", "确认");
                }
            }
        };

		//原始处理方案,省了Unity进度条等花里胡哨的东西。
  		// for (int i = 0; i < files.Length; i++)
        // {
    
    
        //     if (!files[i].Name.EndsWith(".png") && !files[i].Name.EndsWith(".jpg")) continue;
        //     string xmlName = files[i].Name.Split('.')[0];
        //     Debug.Log("imageName:" + xmlName);
        //     var myBitmap = new System.Drawing.Bitmap(files[i].FullName);
        //     var x = Mathf.CeilToInt(myBitmap.Width * 720 / 1080f);
        //     Debug.Log("x:" + x);
        //     var y = Mathf.CeilToInt(myBitmap.Height * 1440 / 2160f);
        //     Debug.Log("y:" + y);
        //     var b = new System.Drawing.Bitmap(x, y);
        //     var g = System.Drawing.Graphics.FromImage(b);
        //     // 插值算法的质量 
        //     g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
        //     g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
        //     g.DrawImage(myBitmap, new System.Drawing.Rectangle(0, 0, x, y),
        //         new System.Drawing.Rectangle(0, 0, myBitmap.Width, myBitmap.Height),
        //         System.Drawing.GraphicsUnit.Pixel);
        //     g.Dispose();
        //     myBitmap.Dispose();
        //     b.Save(files[i].FullName);
        //     b.Dispose();
        // }
    }

Here only the size of the picture is changed, and other attributes can be changed by analogy.

Of course, one thing to note is that the System.Drawing class used in the code is not included in Unity.
We can achieve the purpose of using this class by adding the file System.Drawing.dll in the Plugins directory.
Alternatively, solutions can be generated directly through C#. That is, directly use C# to use the original processing scheme and some codes to generate windows desktop programs for processing. Because many tools include this tool class by default when you create a C# solution.
insert image description here

In addition, it is possible that the following error may appear during your processing.Please add a picture description

If you make this kind of error, you can check whether there is any problem with the parameters you pass, because if you calculate the width and height of the image, it is very likely that a certain value is 0 due to rounding, and this error may be reported at this time.

that's all.

I took the time to sort out the tools, and you can download and try them out. Project link
You can download the following files to use.
insert image description here
The function is probably to specify the file or folder to process the image size according to the format.

insert image description here

Guess you like

Origin blog.csdn.net/qq_39860954/article/details/127395695
Recommended