ImagesClip.cs 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262
  1. using GFGEditor;
  2. using GFGGame;
  3. using System;
  4. using System.Collections;
  5. using System.Collections.Generic;
  6. using System.Drawing;
  7. using System.Drawing.Imaging;
  8. using System.IO;
  9. using UnityEngine;
  10. using Color = System.Drawing.Color;
  11. using Graphics = System.Drawing.Graphics;
  12. public class ImagesClip : MonoBehaviour
  13. {
  14. public static void CutImageWhitePart(string FilePath, string TargetPath, string fileName, int WhiteBarRate = 2)
  15. {
  16. Debug.Log("fileName:" + fileName);
  17. Bitmap bmp = new Bitmap(FilePath);
  18. int top = 0, left = 0;
  19. int right = bmp.Width, bottom = bmp.Height;
  20. int width = bmp.Width, height = bmp.Height;
  21. int xLeft = 0, yTop = 0;
  22. //寻找最上面的标线,从左(0)到右,从上(0)到下
  23. for (int i = 0; i < bmp.Height; i++)//行
  24. {
  25. bool find = false;
  26. for (int j = 0; j < bmp.Width; j++)//列
  27. {
  28. Color c = bmp.GetPixel(j, i);
  29. if (IsBlank(c))
  30. {
  31. top = i;
  32. find = true;
  33. yTop = i;
  34. break;
  35. }
  36. }
  37. if (find) break;
  38. }
  39. //寻找最左边的标线,从上(top位)到下,从左到右
  40. for (int i = 0; i < bmp.Width; i++)//列
  41. {
  42. bool find = false;
  43. for (int j = top; j < bmp.Height; j++)//行
  44. {
  45. Color c = bmp.GetPixel(i, j);
  46. if (IsBlank(c))
  47. {
  48. left = i;
  49. find = true;
  50. xLeft = i;
  51. break;
  52. }
  53. }
  54. if (find) break; ;
  55. }
  56. //寻找最下边标线,从下到上,从左到右
  57. for (int i = bmp.Height - 1; i >= 0; i--)//行
  58. {
  59. bool find = false;
  60. for (int j = left; j < bmp.Width; j++)//列
  61. {
  62. Color c = bmp.GetPixel(j, i);
  63. if (IsBlank(c))
  64. {
  65. bottom = i;
  66. find = true;
  67. break;
  68. }
  69. }
  70. if (find) break;
  71. }
  72. //寻找最右边的标线,从上到下,从右往左
  73. for (int i = bmp.Width - 1; i >= 0; i--)//列
  74. {
  75. bool find = false;
  76. for (int j = 0; j < bottom; j++)//行
  77. {
  78. Color c = bmp.GetPixel(i, j);
  79. if (IsBlank(c))
  80. {
  81. right = i;
  82. find = true;
  83. break;
  84. }
  85. }
  86. if (find) break;
  87. }
  88. bmp = Cut(bmp, left, top, right - left + 1, bottom - top + 1);
  89. if (bmp != null)
  90. {
  91. bmp.Save(TargetPath + fileName);
  92. WriteImagePos(TargetPath, fileName, xLeft + (bmp.Width / 2) - (width / 2), yTop + (bmp.Height / 2) - (height / 2));
  93. bmp.Dispose();
  94. Debug.Log("换装部件裁剪完成");
  95. }
  96. }
  97. public static Bitmap Cut(Bitmap b, int StartX, int StartY, int iWidth, int iHeight)
  98. {
  99. if (b == null)
  100. {
  101. return null;
  102. }
  103. int w = b.Width;
  104. int h = b.Height;
  105. if (StartX >= w || StartY >= h)
  106. {
  107. return null;
  108. }
  109. if (StartX + iWidth > w)
  110. {
  111. iWidth = w - StartX;
  112. }
  113. if (StartY + iHeight > h)
  114. {
  115. iHeight = h - StartY;
  116. }
  117. try
  118. {
  119. Bitmap bmpOut = new Bitmap(iWidth, iHeight, PixelFormat.Format32bppArgb);
  120. Graphics g = Graphics.FromImage(bmpOut);
  121. g.DrawImage(b, new Rectangle(0, 0, iWidth, iHeight), new Rectangle(StartX, StartY, iWidth, iHeight), GraphicsUnit.Pixel);
  122. g.Dispose();
  123. return bmpOut;
  124. }
  125. catch
  126. {
  127. return null;
  128. }
  129. }
  130. /// <summary>
  131. /// 判断空白与否
  132. /// </summary>
  133. /// <param name="c"></param>
  134. /// <returns></returns>
  135. public static bool IsBlank(Color c)
  136. {
  137. // Debug.Log("r:" + c.R + " G:" + c.G + " b:" + c.B + " a:" + c.A);
  138. if ((c.R <= 255 || c.G <= 255 || c.B <= 255) && c.A > 0)
  139. return true;
  140. else return false;
  141. }
  142. public static List<string> ReadImagePosition()
  143. {
  144. string targetPath = ImportArtResTool.DressUpTargetPath; ;
  145. string sourcePath = ImportArtResTool.DressUpTargetPath;
  146. string[] includeExtensionNames = new string[] { ".png", ".jpg" };
  147. List<string> result = new List<string>();
  148. if (Directory.Exists(sourcePath))
  149. {
  150. var files = Directory.GetFiles(sourcePath);
  151. foreach (var file in files)
  152. {
  153. if (file.Trim() == file)
  154. {
  155. string extensionName = Path.GetExtension(file);//获取扩展名
  156. if (includeExtensionNames == null || Array.IndexOf(includeExtensionNames, extensionName) >= 0)
  157. {
  158. string fileName = Path.GetFileName(file);//返回指定路径字符串的文件名和扩展名。
  159. int xImage = 0;
  160. int yImage = 0;
  161. ReadImagePos(targetPath, fileName, out xImage, out yImage);
  162. }
  163. }
  164. else
  165. {
  166. Debug.LogError($"请检查文件名 {file}");
  167. }
  168. }
  169. }
  170. return result;
  171. }
  172. private static void WriteImagePos(string targetPath, string imageName, int iamgeX, int imageY)
  173. {
  174. string savePath = Path.Combine(targetPath, imageName.Split('.')[0] + ".bytes");
  175. using (var writer = new BinaryWriter(File.Open(savePath, FileMode.Create)))
  176. {
  177. writer.Write(iamgeX);
  178. writer.Write(imageY);
  179. writer.Close();
  180. }
  181. }
  182. private static void ReadImagePos(string targetPath, string imageName, out int imageX, out int imageY)
  183. {
  184. string savePath = Path.Combine(targetPath, imageName.Split('.')[0] + ".bytes");
  185. try
  186. {
  187. byte[] data = File.ReadAllBytes(savePath);
  188. var reader = new BinaryReader(new MemoryStream(data));
  189. imageX = reader.ReadInt32();
  190. imageY = reader.ReadInt32();
  191. reader.Close();
  192. Debug.Log(imageName + " iamgeX:" + imageX + " iamgeY:" + imageY);
  193. }
  194. catch
  195. {
  196. imageX = 0;
  197. imageY = 0;
  198. Debug.Log(imageName + "未写入位置数据");
  199. }
  200. }
  201. public static void WriteSourceImagesMD5(Dictionary<string, string> resMd5, string saveName)
  202. {
  203. string savePath = Path.Combine(ImportArtResTool.Md5FilePath, saveName);
  204. Debug.Log("savePath:" + savePath + " saveName:" + saveName);
  205. using (var writer = new BinaryWriter(File.Open(savePath, FileMode.Create)))
  206. {
  207. ICollection keys = resMd5.Keys;
  208. foreach (string key in keys)
  209. {
  210. writer.Write(key);
  211. writer.Write(resMd5[key]);
  212. }
  213. writer.Close();
  214. // 稍微延迟关闭文件流
  215. System.Threading.Thread.Sleep(100); // 可以根据需要调整延迟时间
  216. }
  217. }
  218. public static Dictionary<string, string> ReadSourceImagesMD5(string saveName)
  219. {
  220. string savePath = Path.Combine(ImportArtResTool.Md5FilePath, saveName);
  221. Dictionary<string, string> resMd5 = new Dictionary<string, string>();
  222. try
  223. {
  224. byte[] data = File.ReadAllBytes(savePath);
  225. var reader = new BinaryReader(new MemoryStream(data));
  226. bool isReadEnd = false;
  227. while (!isReadEnd)
  228. {
  229. try
  230. {
  231. string key = reader.ReadString();
  232. string value = reader.ReadString();
  233. resMd5.Add(key, value);
  234. }
  235. catch
  236. {
  237. isReadEnd = true;
  238. }
  239. }
  240. reader.Close();
  241. }
  242. catch
  243. {
  244. Debug.Log(savePath + "不存在");
  245. }
  246. return resMd5;
  247. }
  248. }