源战役客户端
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

839 line
28 KiB

  1. using UnityEngine;
  2. using UnityEditor;
  3. using UnityEngine.UI;
  4. using System.Collections;
  5. using System.Collections.Generic;
  6. using System;
  7. using System.IO;
  8. using System.Text.RegularExpressions;
  9. using System.Drawing;
  10. using System.Drawing.Imaging;
  11. public class TextureCutoff : EditorWindow
  12. {
  13. private static TextureCutoff instance;
  14. static Texture2D _targetPic;
  15. static string _pathRoot;
  16. static float _alpha_cut_off = 0;
  17. static int _horizontalSpace = 0;
  18. static int _verticalSpace = 0;
  19. static int _rate = 10;
  20. static int _rateImage = 1;
  21. static bool _isCover = true;
  22. static string[] formatOption = new string[] { "最临近点插值(有锯齿,速度快)", "双线性插值(无锯齿,速度中等)", "双立方插值(质量最高,速度慢)" };
  23. static int _indexOfFormat;
  24. static string _outputPaht;
  25. static bool _isOutputDir;
  26. static bool _isSinglePath;
  27. static int _forceHeight = 512;
  28. static int _forceWidth = 512;
  29. static bool _autoCheck = true;
  30. static bool _auto2up;
  31. static bool _auto2dowm;
  32. static bool _isTip;
  33. static bool _isTip3;
  34. static bool _mode_pot = true;
  35. /// <summary>
  36. /// 自动裁剪模式:选择相近的尺寸
  37. /// </summary>
  38. static bool _auto2near = true;
  39. /// <summary>
  40. /// 是否开启自动剔除透明像素
  41. /// </summary>
  42. static bool _isCutOffImg;
  43. static int _testInt;
  44. [MenuItem("Tools/裁剪图片")]
  45. static void ShowExcelTools()
  46. {
  47. Init();
  48. instance.Show();
  49. }
  50. void OnGUI()
  51. {
  52. DrawOptions();
  53. }
  54. private void DrawOptions()
  55. {
  56. _isSinglePath = EditorGUILayout.Toggle("是否处理单个文件", _isSinglePath);
  57. if (_isSinglePath)
  58. {
  59. _targetPic = EditorGUILayout.ObjectField("指定单个文件", _targetPic, typeof(Texture2D), false) as Texture2D;
  60. _pathRoot = AssetDatabase.GetAssetPath(_targetPic).Replace("Assets", Application.dataPath);
  61. if (GUILayout.Button("获取文件夹目录"))
  62. {
  63. _pathRoot = _pathRoot.Substring(0, _pathRoot.LastIndexOf("/"));
  64. _isSinglePath = false;
  65. }
  66. }
  67. _pathRoot = EditorGUILayout.TextField("指定目录", _pathRoot);
  68. if (_isSinglePath)
  69. {
  70. EditorGUILayout.HelpBox("处理 单个文件 模式", MessageType.Info, true);
  71. }
  72. else
  73. {
  74. EditorGUILayout.HelpBox("处理 批量文件夹 模式", MessageType.Info, true);
  75. }
  76. EditorGUILayout.Space();
  77. EditorGUILayout.Space();
  78. EditorGUILayout.Space();
  79. EditorGUILayout.Space();
  80. _autoCheck = EditorGUILayout.Toggle("是否自动裁剪", _autoCheck);
  81. if (_autoCheck)
  82. {
  83. //EditorGUILayout.HorizontalScope hs = new EditorGUILayout.HorizontalScope();
  84. //GUILayout.FlexibleSpace();
  85. _mode_pot = EditorGUILayout.Toggle("是否2次幂", _mode_pot);
  86. if(_mode_pot)
  87. {
  88. var auto2up = EditorGUILayout.Toggle("模式:只向上", _auto2up);
  89. if (auto2up)
  90. {
  91. _auto2up = auto2up;
  92. _auto2dowm = false;
  93. _auto2near = false;
  94. }
  95. else
  96. {
  97. if (!_auto2dowm && !_auto2near)
  98. {
  99. _auto2up = true;
  100. }
  101. }
  102. var auto2dowm = EditorGUILayout.Toggle("模式:只向下", _auto2dowm);
  103. if (auto2dowm)
  104. {
  105. _auto2dowm = true;
  106. _auto2up = false;
  107. _auto2near = false;
  108. }
  109. else
  110. {
  111. if (!_auto2up && !_auto2near)
  112. {
  113. _auto2dowm = true;
  114. }
  115. }
  116. var auto2near = EditorGUILayout.Toggle("模式:尺寸接近", _auto2near);
  117. if (auto2near)
  118. {
  119. _auto2near = true;
  120. _auto2dowm = false;
  121. _auto2up = false;
  122. }
  123. else
  124. {
  125. if (!_auto2dowm && !_auto2up)
  126. {
  127. _auto2near = true;
  128. }
  129. }
  130. // hs.Dispose();
  131. if (_auto2up)
  132. {
  133. if (_mode_pot)
  134. {
  135. EditorGUILayout.HelpBox("图片尺寸只会 向上缩放 成2的幂次", MessageType.Info, true);
  136. }
  137. else
  138. {
  139. EditorGUILayout.HelpBox("图片尺寸只会 向上缩放 成4的倍数", MessageType.Info, true);
  140. }
  141. }
  142. else if (_auto2dowm)
  143. {
  144. if (_mode_pot)
  145. {
  146. EditorGUILayout.HelpBox("图片尺寸只会 向下缩放 成2的幂次", MessageType.Info, true);
  147. }
  148. else
  149. {
  150. EditorGUILayout.HelpBox("图片尺寸只会 向下缩放 成4的倍数", MessageType.Info, true);
  151. }
  152. }
  153. else if (_auto2near)
  154. {
  155. if (_mode_pot)
  156. {
  157. EditorGUILayout.HelpBox("图片尺寸会缩放到 最接近 的2次幂", MessageType.Info, true);
  158. }
  159. else
  160. {
  161. EditorGUILayout.HelpBox("图片尺寸会缩放到 最接近 的4的倍数", MessageType.Info, true);
  162. }
  163. }
  164. }
  165. else
  166. {
  167. EditorGUILayout.HelpBox("图片尺寸会缩放到 最接近 的4的倍数", MessageType.Info, true);
  168. }
  169. }
  170. else
  171. {
  172. _forceWidth = EditorGUILayout.IntField("强制宽度", _forceWidth);
  173. _forceHeight = EditorGUILayout.IntField("强制高度", _forceHeight);
  174. EditorGUILayout.HelpBox("图片将会被强制缩放成 " + _forceHeight + " x " + _forceHeight, MessageType.Info, true);
  175. }
  176. EditorGUILayout.Space();
  177. _indexOfFormat = EditorGUILayout.Popup("缩放算法", _indexOfFormat, formatOption);
  178. if (_indexOfFormat == 2 && !_isTip3)
  179. {
  180. if (!EditorUtility.DisplayDialog("提示", "因为算法原因,在得到最高质量的同时,透明区域会被增强,导致和原图不一致,请确认", "继续", "取消"))
  181. {
  182. _indexOfFormat = 0;
  183. }
  184. else
  185. {
  186. _isTip3 = true;
  187. }
  188. }
  189. else if (_indexOfFormat == 1 && !_isTip)
  190. {
  191. string str = "虽然使用这个算法可以得到相对无锯齿的图片,但是也会导致图片看起来相对模糊\n当前项目不推荐使用,具体原因详见文档\n当然,如果你只是想看看效果,请点击继续";
  192. if (!EditorUtility.DisplayDialog("提示", str, "继续", "取消"))
  193. {
  194. _indexOfFormat = 0;
  195. }
  196. else
  197. {
  198. _isTip = true;
  199. }
  200. }
  201. EditorGUILayout.Space();
  202. EditorGUILayout.Space();
  203. EditorGUILayout.Space();
  204. EditorGUILayout.Space();
  205. EditorGUILayout.ToggleGroupScope tgs = new EditorGUILayout.ToggleGroupScope("是否启用裁剪无用像素", _isCutOffImg);
  206. _isCutOffImg = tgs.enabled;
  207. _alpha_cut_off = EditorGUILayout.FloatField("alpha剔除", _alpha_cut_off);
  208. EditorGUILayout.HelpBox("图片中低于这个数值的透明度将会被视为 完全透明 而被剔除", MessageType.Info, true);
  209. var space = EditorGUILayout.Vector2Field("边界扩展", new Vector2(_horizontalSpace, _verticalSpace));
  210. _horizontalSpace = (int)space.x;
  211. _verticalSpace = (int)space.y;
  212. tgs.Dispose();
  213. _isCover = EditorGUILayout.Toggle("是否覆盖文件", _isCover);
  214. if (_isCover)
  215. {
  216. EditorGUILayout.HelpBox("源文件将会被覆盖", MessageType.Warning, true);
  217. _isOutputDir = false;
  218. }
  219. else
  220. {
  221. _isOutputDir = EditorGUILayout.Toggle("是否合并输出在同一个目录", _isOutputDir);
  222. if (_isOutputDir)
  223. {
  224. _outputPaht = EditorGUILayout.TextField("输出目录", _outputPaht);
  225. EditorGUILayout.HelpBox("所有图片会集中输出在这个目录中", MessageType.Warning, true);
  226. }
  227. else
  228. {
  229. EditorGUILayout.HelpBox("将会输出源文件路径下 xxx_cutoff.jpg/png", MessageType.Warning, true);
  230. }
  231. }
  232. if (GUILayout.Button("转换"))
  233. {
  234. EditorCoroutineRunner.StartEditorCoroutine(Conver());
  235. }
  236. //_testInt = EditorGUILayout.IntField("测试Int", _testInt);
  237. //if (GUILayout.Button("测试"))
  238. //{
  239. // //Bitmap bit = new Bitmap(_pathRoot);
  240. // //ChangeTextureSize(bit, _pathRoot);
  241. // //int i = 10;
  242. // Debug.Log(Mathf.RoundToInt(0.624f));
  243. // Debug.Log(Mathf.RoundToInt(0.424f));
  244. // Debug.Log(Mathf.Round(0.624f));
  245. // Debug.Log(Mathf.Round(0.424f));
  246. // Debug.Log(Math.Round(0.624f));
  247. // Debug.Log(Mathf.Round(0.424f));
  248. //}
  249. }
  250. IEnumerator Conver()
  251. {
  252. List<string> texturePahts = new List<string>();
  253. if (_isSinglePath)
  254. {
  255. texturePahts.Add(_pathRoot);
  256. }
  257. else
  258. {
  259. if (!Directory.Exists(_pathRoot))
  260. {
  261. EditorUtility.DisplayDialog("错误", "目录不存在或者不是文件夹目录\n" + _pathRoot, "确定", "");
  262. yield break;
  263. }
  264. }
  265. float count = 0;
  266. if (!_isSinglePath) //检查整个文件夹
  267. {
  268. string[] files = new string[1];
  269. files = Directory.GetFiles(_pathRoot, "*png*", SearchOption.AllDirectories);
  270. foreach (var file in files)
  271. {
  272. count++;
  273. if (file.EndsWith(".png"))
  274. {
  275. var clearPaht = file;
  276. texturePahts.Add(clearPaht);
  277. //Debug.Log(clearPaht);
  278. if (count % _rate == 0)
  279. {
  280. yield return 1;
  281. }
  282. EditorUtility.DisplayProgressBar("查找文件中的PNG···", "查找中 " + file, count / files.Length);
  283. }
  284. }
  285. files = Directory.GetFiles(_pathRoot, "*jpg*", SearchOption.AllDirectories);
  286. foreach (var file in files)
  287. {
  288. count++;
  289. if (file.EndsWith(".jpg"))
  290. {
  291. var clearPaht = file;
  292. texturePahts.Add(clearPaht);
  293. //Debug.Log(clearPaht);
  294. if (count % _rate == 0)
  295. {
  296. yield return 1;
  297. }
  298. EditorUtility.DisplayProgressBar("查找文件中的JPG···", "查找中 " + file, count / files.Length);
  299. }
  300. }
  301. if(_isOutputDir)
  302. {
  303. string newDir = _outputPaht;
  304. if (!Directory.Exists(newDir))
  305. {
  306. EditorUtility.DisplayDialog("错误", "输出目录不存在\n" + _outputPaht, "确定", "");
  307. yield break;
  308. }
  309. if (texturePahts.Count > 0)
  310. {
  311. Directory.CreateDirectory(newDir);
  312. }
  313. }
  314. }
  315. count = 0;
  316. foreach (var singlePaht in texturePahts)
  317. {
  318. count++;
  319. Bitmap prefab = new Bitmap(singlePaht);
  320. var format = prefab.RawFormat;
  321. if (prefab != null)
  322. {
  323. if (_isCutOffImg)
  324. {
  325. var clearImg = CreateNewTexture(prefab, singlePaht);
  326. if (clearImg != null)
  327. {
  328. prefab.Dispose();
  329. prefab = clearImg;
  330. }
  331. }
  332. ChangeTextureSize(prefab, singlePaht, format);
  333. }
  334. if (count % _rateImage == 0)
  335. {
  336. yield return 1;
  337. }
  338. EditorUtility.DisplayProgressBar("创建图片中···", singlePaht, count / texturePahts.Count);
  339. }
  340. EditorUtility.ClearProgressBar();
  341. AssetDatabase.Refresh();
  342. }
  343. void ChangeTextureSize(Bitmap pic, string path, System.Drawing.Imaging.ImageFormat format)
  344. {
  345. int newHeight = 0;
  346. int newWidth = 0;
  347. if (_autoCheck)
  348. {
  349. if (_mode_pot)
  350. {
  351. if (pic.Width > pic.Height) //区尺寸中较大值去计算接近的POT
  352. {
  353. newWidth = GetPOT(pic.Width);
  354. newHeight = newWidth;
  355. }
  356. else
  357. {
  358. newHeight = GetPOT(pic.Height);
  359. newWidth = newHeight;
  360. }
  361. }
  362. else
  363. {
  364. newWidth = GetMOF(pic.Width);
  365. newHeight = GetMOF(pic.Height);
  366. }
  367. }
  368. else
  369. {
  370. newHeight = _forceHeight;
  371. newWidth = _forceWidth;
  372. }
  373. if(newHeight == pic.Height && newWidth == pic.Width)
  374. {
  375. return;
  376. }
  377. Bitmap img = new Bitmap(pic, newWidth, newHeight);
  378. System.Drawing.Color[,] cols = new System.Drawing.Color[pic.Width, pic.Height];
  379. //缓存所有像素
  380. for (int i = 0; i < pic.Width; i++)
  381. {
  382. for (int j = 0; j < pic.Height; j++)
  383. {
  384. cols[i, j] = pic.GetPixel(i, j);
  385. }
  386. }
  387. double scale_x = newWidth / (float)pic.Width; //长度缩放比
  388. double scale_y = newHeight / (float)pic.Height; //宽度缩放比
  389. //Debug.LogFormat("新宽高:{0} x {1}", newWidth, newHeight);
  390. if (_indexOfFormat == 2)
  391. {
  392. ////双立方差值 算法 --内置的
  393. System.Drawing.Graphics g = System.Drawing.Graphics.FromImage(img);
  394. g.DrawImage(img, 0, 0, newWidth, newHeight);
  395. }
  396. else
  397. {
  398. //填充新尺寸图片的每个像素
  399. for (int i = 0; i < newWidth; i++)
  400. {
  401. for (int j = 0; j < newHeight; j++)
  402. {
  403. if (_indexOfFormat == 0)
  404. {
  405. //最近像素 算法
  406. int sample_x = (int)Math.Round(i / scale_x, MidpointRounding.AwayFromZero); //原图中对应的X
  407. int sample_y = (int)Math.Round(j / scale_y, MidpointRounding.AwayFromZero);//原图中对应的Y
  408. sample_x = Mathf.Clamp(sample_x, 0, pic.Width - 1);
  409. sample_y = Mathf.Clamp(sample_y, 0, pic.Height - 1);
  410. try
  411. {
  412. var tempCol = cols[sample_x, sample_y];
  413. if (tempCol.A != 0)
  414. {
  415. img.SetPixel(i, j, cols[sample_x, sample_y]);
  416. }
  417. }
  418. catch (Exception exp)
  419. {
  420. Debug.LogError(exp);
  421. Debug.LogErrorFormat("{0},{1}", i, j);
  422. }
  423. }
  424. else if (_indexOfFormat == 1)
  425. {
  426. int sample_x = 0;
  427. int sample_y = 0;
  428. System.Drawing.Color final;
  429. //双线滤波 算法
  430. if (scale_x > 1 && scale_y < 1)
  431. {
  432. int min = (int)(i / scale_x);
  433. int max = min + 1;
  434. max = Mathf.Clamp(max, 0, pic.Width - 1);
  435. double delta = (i / scale_x) - min;
  436. sample_y = (int)Math.Round(j / scale_y);//原图中对应的Y
  437. final = LerpColor(cols[min, sample_y], cols[max, sample_y], (float)delta);
  438. }
  439. else if (scale_y > 1 && scale_x < 1)
  440. {
  441. int min = (int)(j / scale_y);
  442. int max = min + 1;
  443. max = Mathf.Clamp(max, 0, pic.Height - 1);
  444. double delta = (j / scale_y) - min;
  445. sample_x = (int)Math.Round(i / scale_x); //原图中对应的X
  446. final = LerpColor(cols[sample_x, min], cols[sample_x, max], (float)delta);
  447. }
  448. else if (scale_x > 1 && scale_y > 1)
  449. {
  450. int min_x = (int)(i / scale_x);
  451. int max_x = min_x + 1;
  452. max_x = Mathf.Clamp(max_x, 0, pic.Width - 1);
  453. double delta_x = (i / scale_x) - min_x;
  454. int min_y = (int)(j / scale_y);
  455. int max_y = min_y + 1;
  456. max_y = Mathf.Clamp(max_y, 0, pic.Height - 1);
  457. double delta_y = (j / scale_y) - min_y;
  458. var final_x = LerpColor(cols[min_x, min_y], cols[max_x, min_y], (float)delta_x);
  459. var final_y = LerpColor(cols[min_x, max_y], cols[max_x, max_y], (float)delta_x);
  460. final = LerpColor(final_x, final_y, (float)delta_y);
  461. }
  462. else
  463. {
  464. //最近像素 算法
  465. sample_x = (int)Math.Round(i / scale_x); //原图中对应的X
  466. sample_y = (int)Math.Round(j / scale_y);//原图中对应的Y
  467. sample_x = Mathf.Clamp(sample_x, 0, pic.Width - 1);
  468. sample_y = Mathf.Clamp(sample_y, 0, pic.Height - 1);
  469. final = cols[sample_x, sample_y];
  470. //System.Drawing.Graphics g = System.Drawing.Graphics.FromImage(img);
  471. //g.DrawImage(img, 0, 0, 512.0f, 512.0f);
  472. }
  473. try
  474. {
  475. img.SetPixel(i, j, final);
  476. }
  477. catch (Exception exp)
  478. {
  479. Debug.LogError(exp);
  480. Debug.LogErrorFormat("{0},{1}", i, j);
  481. }
  482. }
  483. }
  484. }
  485. }
  486. string fileName;
  487. path = path.Replace("\\", "/");
  488. //if (_isCover)
  489. //{
  490. fileName = path.Substring(path.LastIndexOf("/"));
  491. //}
  492. //else
  493. //{
  494. //fileName = path.Substring(path.LastIndexOf("\\"));
  495. //}
  496. //img = new Bitmap(512, 512);
  497. //for(int i = 1;i<512;i++)
  498. //{
  499. // for(int j = 1;j<512;j++)
  500. // {
  501. // img.SetPixel(i, j, System.Drawing.Color.FromArgb(255,255,255,255));
  502. // }
  503. //}
  504. string newDir = _outputPaht;
  505. if (_isOutputDir) //在统一目录输出
  506. {
  507. if (!Directory.Exists(newDir))
  508. {
  509. Directory.CreateDirectory(newDir);
  510. }
  511. newDir += fileName;
  512. }
  513. else
  514. {
  515. if (_isCover)
  516. {
  517. newDir = path;
  518. }
  519. else
  520. {
  521. newDir = path.Replace(".", "_cutoff.");
  522. }
  523. }
  524. if (_isCover)
  525. {
  526. pic.Dispose();
  527. img.Save(newDir);
  528. }
  529. else
  530. {
  531. pic.Dispose();
  532. img.Save(newDir);
  533. }
  534. Debug.Log(format);
  535. }
  536. System.Drawing.Color LerpColor(System.Drawing.Color col1, System.Drawing.Color col2, float delta)
  537. {
  538. var col = System.Drawing.Color.FromArgb((int)Mathf.Lerp(col1.A, col2.A, delta), (int)Mathf.Lerp(col1.R, col2.R, delta), (int)Mathf.Lerp(col1.G, col2.G, delta), (int)Mathf.Lerp(col1.B, col2.B, delta));
  539. return col;
  540. }
  541. int GetPOT(int cur)
  542. {
  543. float check = 0;
  544. for (int i = 1; i < 12; i++)
  545. {
  546. check = Mathf.Pow(2, i);
  547. if (_auto2up)
  548. {
  549. if (check > cur)
  550. {
  551. return (int)check;
  552. }
  553. }
  554. else if (_auto2dowm)
  555. {
  556. if (check > cur)
  557. {
  558. return (int)Mathf.Pow(2, i - 1);
  559. }
  560. }
  561. else if (_auto2near)
  562. {
  563. if (check > cur)
  564. {
  565. float last = Mathf.Pow(2, i - 1);
  566. float upDelta = check - cur;
  567. float dowmDelta = cur - last;
  568. if (upDelta >= dowmDelta)
  569. {
  570. return (int)last;
  571. }
  572. else
  573. {
  574. return (int)check;
  575. }
  576. }
  577. }
  578. }
  579. return 0;
  580. }
  581. int GetMOF(int cur)
  582. {
  583. int x = cur / 4;
  584. return 4 * x;
  585. }
  586. Bitmap CreateNewTexture(Bitmap pic, string path)
  587. {
  588. if (path.EndsWith(".jpg")) //JPG没有通明通道
  589. {
  590. return pic;
  591. }
  592. Vector2 range_x = new Vector2(0, pic.Width);
  593. Vector2 range_y = new Vector2(0, pic.Height);
  594. //Debug.Log("图片尺寸 " + pic.Width + "," + pic.Width);
  595. bool done = false;
  596. //横轴扫描 从左到右
  597. for (int i = 0; i < pic.Width; i++)
  598. {
  599. if (done)
  600. {
  601. break;
  602. }
  603. for (int j = 0; j < pic.Height; j++)
  604. {
  605. System.Drawing.Color col = pic.GetPixel(i, j);
  606. // data[i, j] = col;
  607. if (col.A > _alpha_cut_off)
  608. {
  609. range_x.x = i;
  610. // Debug.LogFormat(" 从左到右点 {0},{1},{2}", i, j, col);
  611. done = true;
  612. break;
  613. }
  614. }
  615. }
  616. done = false;
  617. //横轴扫描 从右到左
  618. for (int i = pic.Width - 1; i > 0; i--)
  619. {
  620. if (done)
  621. {
  622. break;
  623. }
  624. for (int j = 0; j < pic.Height; j++)
  625. {
  626. System.Drawing.Color col = pic.GetPixel(i, j);
  627. // data[i, j] = col;
  628. if (col.A > _alpha_cut_off)
  629. {
  630. range_x.y = i + 1;
  631. //Debug.LogFormat(" 从右到左点 {0},{1}", range_x.y, j, col);
  632. done = true;
  633. break;
  634. }
  635. }
  636. }
  637. done = false;
  638. //纵轴扫描 从下到上
  639. for (int i = 0; i < pic.Height; i++)
  640. {
  641. if (done)
  642. {
  643. break;
  644. }
  645. for (int j = 0; j < pic.Width; j++)
  646. {
  647. System.Drawing.Color col = pic.GetPixel(j, i);
  648. // data[i, j] = col;
  649. if (col.A > _alpha_cut_off)
  650. {
  651. range_y.x = i;
  652. // Debug.LogFormat(" 从下到上点 {0},{1}", range_y.x, i, col);
  653. done = true;
  654. break;
  655. }
  656. }
  657. }
  658. done = false;
  659. //纵轴扫描 从上到下
  660. for (int i = pic.Height - 1; i > 0; i--)
  661. {
  662. if (done)
  663. {
  664. break;
  665. }
  666. for (int j = 0; j < pic.Width; j++)
  667. {
  668. System.Drawing.Color col = pic.GetPixel(j, i);
  669. // data[i, j] = col;
  670. if (col.A > _alpha_cut_off)
  671. {
  672. range_y.y = i + 1;
  673. // Debug.LogFormat(" 从上到下点 {0},{1}", range_y.y, i,col);
  674. done = true;
  675. break;
  676. }
  677. }
  678. }
  679. if (range_x.x > range_x.y)
  680. {
  681. //Debug.LogError("查找错误 ");
  682. return null;
  683. }
  684. if (range_y.x > range_y.y)
  685. {
  686. //Debug.LogError("查找错误 ");
  687. return null;
  688. }
  689. range_x.x = Mathf.Clamp(range_x.x, 0, pic.Width);
  690. range_x.y = Mathf.Clamp(range_x.y, 0, pic.Width);
  691. range_y.x = Mathf.Clamp(range_y.x, 0, pic.Height);
  692. range_y.y = Mathf.Clamp(range_y.y, 0, pic.Height);
  693. // Debug.Log(range_x);
  694. // Debug.Log(range_y);
  695. // Debug.LogFormat("最左边的像素:{0},最后边的像素:{1},最上像素:{2},最下的像素:{3}", range_x.x, range_x.y, range_y.x, range_y.y);
  696. Vector2 newSize = new Vector2(range_x.y - range_x.x, range_y.y - range_y.x);
  697. Bitmap newImg = new Bitmap((int)newSize.x + _horizontalSpace * 2, (int)newSize.y + _verticalSpace * 2, pic.PixelFormat);
  698. for (var i = range_x.x; i < range_x.y; i++)
  699. {
  700. for (var j = range_y.x; j < range_y.y; j++)
  701. {
  702. System.Drawing.Color col = pic.GetPixel((int)i, (int)j);
  703. //print(col);
  704. //col = new Color(255, 0, 0, 0);
  705. //Debug.Log((i - range_x.x) + "," + (j - range_y.x));
  706. try
  707. {
  708. newImg.SetPixel((int)(i - range_x.x) + _horizontalSpace, (int)(j - range_y.x) + _verticalSpace, col);
  709. }
  710. catch
  711. {
  712. Debug.LogErrorFormat("{0},{1}", (int)(i - range_x.x) + _horizontalSpace, (int)(j - range_y.x) + _verticalSpace);
  713. }
  714. }
  715. }
  716. //Debug.Log(newSize);
  717. //Debug.Log(newSize.x - _horizontalSpace);
  718. //Debug.Log(newSize.y - _verticalSpace);
  719. //填充空白透明像素
  720. for (int i = 0; i < newImg.Width; i++)
  721. {
  722. for (int j = 0; j < newImg.Height; j++)
  723. {
  724. if (i < _horizontalSpace || i >= (newSize.x + _horizontalSpace))
  725. {
  726. // Debug.Log(i + "," + j);
  727. var col = System.Drawing.Color.FromArgb(0, 0, 0, 0);
  728. newImg.SetPixel(i, j, col);
  729. }
  730. else if (j < _verticalSpace || j >= (newSize.y + _verticalSpace))
  731. {
  732. // Debug.Log(i + ","+ j);
  733. var col = System.Drawing.Color.FromArgb(0, 0, 0, 0);
  734. newImg.SetPixel(i, j, col);
  735. }
  736. }
  737. }
  738. //string newDir = _outputPaht;
  739. //string fileName = path.Substring(path.LastIndexOf("\\"));
  740. //if (_isOutputDir) //在统一目录输出
  741. //{
  742. // if (!Directory.Exists(newDir))
  743. // {
  744. // Directory.CreateDirectory(newDir);
  745. // }
  746. // newDir += fileName;
  747. //}
  748. //else
  749. //{
  750. // if (_isCover)
  751. // {
  752. // newDir = path;
  753. // }
  754. // else
  755. // {
  756. // newDir = path.Replace(".", "_cutoff.");
  757. // }
  758. //}
  759. // Debug.Log(newDir);
  760. //newImg.Save(newDir, System.Drawing.Imaging.ImageFormat.Png);
  761. return newImg;
  762. }
  763. void OnSelectionChange()
  764. {
  765. if (!_isSinglePath)
  766. {
  767. return;
  768. }
  769. object[] selection = (object[])Selection.objects;
  770. //判断是否有对象被选中
  771. if (selection.Length != 1)
  772. return;
  773. if (selection[0].GetType() == typeof(Texture2D))
  774. {
  775. _targetPic = (Texture2D)selection[0];
  776. string objPath = AssetDatabase.GetAssetPath(_targetPic);
  777. _pathRoot = objPath;
  778. Repaint();
  779. }
  780. }
  781. private static void Init()
  782. {
  783. _targetPic = null;
  784. instance = EditorWindow.GetWindow<TextureCutoff>("选项");
  785. _pathRoot = Application.dataPath;
  786. _outputPaht = _pathRoot + "/image_output";
  787. instance.position = new Rect(new Vector2(604, 290), new Vector2(750, 600));
  788. _isTip = false;
  789. _indexOfFormat = 0;
  790. }
  791. }