252 lines
8.6 KiB
C#
252 lines
8.6 KiB
C#
using System;
|
||
using System.Collections;
|
||
using System.Collections.Generic;
|
||
using System.IO;
|
||
using System.Threading.Tasks;
|
||
using Cysharp.Threading.Tasks;
|
||
using HK;
|
||
using HK.FUJIFILM;
|
||
using UnityEngine;
|
||
|
||
public class RenderPrintingManager : MonoBehaviour
|
||
{
|
||
public static RenderPrintingManager Instance;
|
||
|
||
[SerializeField] Camera renderCam;
|
||
[SerializeField] Transform parent;
|
||
|
||
RenderPrintingManagerOption option;
|
||
// RenderPrintingManagerModelOption modelOption;
|
||
|
||
private RenderTexture rendtx;
|
||
string dirPath = Path.Combine(Application.dataPath, "TestPic");
|
||
public string FolderPath;
|
||
|
||
private bool isSaveFinished;
|
||
|
||
public bool IsSaveFinished => isSaveFinished;
|
||
|
||
private void Awake()
|
||
{
|
||
Instance = this;
|
||
var path = Path.Combine(Application.streamingAssetsPath, "PrintingSavePath.txt");
|
||
if (File.Exists(path) && !string.IsNullOrEmpty(File.ReadAllText(path)))
|
||
dirPath = File.ReadAllText(path);
|
||
|
||
if (!Directory.Exists(dirPath))
|
||
{
|
||
Directory.CreateDirectory(dirPath);
|
||
}
|
||
}
|
||
|
||
private void Update()
|
||
{
|
||
// if (Input.GetKeyDown(KeyCode.K))
|
||
// {
|
||
// StartCoroutine(WaitSavePreview());
|
||
// }
|
||
//
|
||
// if (Input.GetKeyDown(KeyCode.L))
|
||
// {
|
||
// StartCoroutine(WaitSavePrinting());
|
||
// }
|
||
}
|
||
|
||
public void StartRenderPrinting(GameObject preview, GameObject design,
|
||
Action<byte[], List<byte[]>, string, List<string>> callback = null)
|
||
{
|
||
isSaveFinished = false;
|
||
var i = PlayerPersistent.GetInt("OrderID");
|
||
FolderPath = Path.Combine(dirPath, $"OrderID_{i}_{DateTime.Now.Ticks}");
|
||
if (!Directory.Exists(FolderPath))
|
||
{
|
||
Directory.CreateDirectory(FolderPath);
|
||
}
|
||
|
||
previewData = new byte[] { };
|
||
printingDatas = new List<byte[]>();
|
||
previewName = "";
|
||
printingNames = new List<string>();
|
||
StartCoroutine(WaitSaveFinish(preview, design, callback));
|
||
}
|
||
|
||
byte[] previewData;
|
||
List<byte[]> printingDatas;
|
||
private string previewName;
|
||
private List<string> printingNames;
|
||
|
||
IEnumerator WaitSaveFinish(GameObject preview, GameObject design,
|
||
Action<byte[], List<byte[]>, string, List<string>> callback)
|
||
{
|
||
if (preview != null)
|
||
yield return StartCoroutine(WaitSavePreview(preview));
|
||
|
||
var designGo = GameObject.Instantiate(design, parent);
|
||
this.option = designGo.GetComponent<RenderPrintingManagerOption>();
|
||
option.GetComponent<RenderPrintingManagerOptionHelper>().ShowAllPrintings();
|
||
option.GetComponent<RenderPrintingManagerOptionHelper>().HideAllPrintings();
|
||
yield return null;
|
||
|
||
for (var i = 0; i < option.objectsToRender.Count; i++)
|
||
{
|
||
foreach (var t in option.objectsToRender)
|
||
{
|
||
t.gameObject.SetActive(false);
|
||
}
|
||
|
||
option.objectsToRender[i].gameObject.SetActive(true);
|
||
yield return StartCoroutine(WaitSavePrinting(designGo));
|
||
}
|
||
|
||
GameObject.Destroy(designGo);
|
||
|
||
callback?.Invoke(previewData, printingDatas, previewName, printingNames);
|
||
isSaveFinished = true;
|
||
}
|
||
|
||
IEnumerator WaitSavePreview(GameObject preview)
|
||
{
|
||
var previewGo = GameObject.Instantiate(preview, parent);
|
||
previewGo.GetComponent<RectTransform>().anchoredPosition = Vector2.zero;
|
||
var modelOption = previewGo.GetComponent<RenderPrintingManagerOption>();
|
||
modelOption.GetComponent<RenderPrintingManagerOptionHelper>().ShowAllPreviews();
|
||
modelOption.GetComponent<RenderPrintingManagerOptionHelper>().HideAllPreviews();
|
||
yield return null;
|
||
|
||
float smallerScale = Mathf.Max(modelOption.renderPreviewSize.x / 400f, modelOption.renderPreviewSize.y / 400f);
|
||
rendtx = new RenderTexture((int)(modelOption.renderPreviewSize.x / smallerScale),
|
||
(int)(modelOption.renderPreviewSize.y / smallerScale), 24,
|
||
RenderTextureFormat.ARGB32);
|
||
modelOption.pivot.transform.localScale = Vector3.one / smallerScale;
|
||
|
||
renderCam.targetTexture = rendtx;
|
||
yield return null;
|
||
Texture2D tex = ToTexture2D(rendtx);
|
||
var bytes = tex.EncodeToPNG();
|
||
var fileName = $"Preview - {DateTime.Now.Ticks}.png";
|
||
var path = Path.Combine(FolderPath, fileName);
|
||
previewName = fileName;
|
||
|
||
// yield return File.WriteAllBytesAsync(path, bytes);
|
||
bool isWriteDone = false;
|
||
Task.Run(() =>
|
||
{
|
||
// 后台线程:仅处理纯文件写入(无引擎资源操作)
|
||
File.WriteAllBytes(path, bytes);
|
||
// 标记完成(线程安全,因为bool是原子操作)
|
||
isWriteDone = true;
|
||
});
|
||
|
||
// 主线程:等待后台线程完成(用循环+yield return null,避免死等)
|
||
while (!isWriteDone)
|
||
{
|
||
yield return null; // 每帧检查一次,不阻塞主线程
|
||
}
|
||
|
||
|
||
previewData = bytes;
|
||
Debug.Log("Preview finish");
|
||
rendtx.Release();
|
||
GameObject.Destroy(previewGo);
|
||
}
|
||
|
||
IEnumerator WaitSavePrinting(GameObject design)
|
||
{
|
||
option.pivot.GetComponent<RectTransform>().anchoredPosition = Vector2.zero;
|
||
option.pivot.transform.localScale = Vector3.one;
|
||
Vector2 printSize = option.renderPrintSize.x == 0 ? option.renderPreviewSize : option.renderPrintSize;
|
||
rendtx = new RenderTexture((int)printSize.x, (int)printSize.y, 24, RenderTextureFormat.ARGB32);
|
||
renderCam.targetTexture = rendtx;
|
||
yield return null;
|
||
Texture2D print_tex = ToTexture2D(rendtx);
|
||
// string uploadTmp = ;
|
||
yield return StartCoroutine(SpecialSaveImageFile(print_tex, "printing"));
|
||
|
||
// var fileInfo = new FileInfo(uploadTmp);
|
||
// var cutBG = fileInfo.Directory.FullName + $"cut bg {fileInfo.Name}";
|
||
|
||
// TODO:褪底功能
|
||
// yield return StartCoroutine(Wait(uploadTmp, cutBG));
|
||
|
||
// Debug.Log(cutBG);
|
||
Debug.Log("finish");
|
||
}
|
||
|
||
private IEnumerator SpecialSaveImageFile(Texture2D tex, string name)
|
||
{
|
||
byte[] bytes = tex.EncodeToPNG();
|
||
|
||
if (!Directory.Exists(FolderPath))
|
||
{
|
||
Directory.CreateDirectory(FolderPath);
|
||
}
|
||
|
||
Debug.Log(FolderPath);
|
||
|
||
var nowTicks = DateTime.Now.Ticks;
|
||
var fileName = $"printing-{nowTicks}.png";
|
||
string filePath = Path.Combine(FolderPath, fileName);
|
||
var changePpi = B83.Image.PNGTools.ChangePPI(bytes, 300, 300);
|
||
// File.WriteAllBytes(outputPath, changePpi);
|
||
|
||
yield return StartCoroutine(PngCompressor.CompressPngAndSetDpiAsync1(changePpi, filePath));
|
||
printingNames.Add(fileName);
|
||
printingDatas.Add(File.ReadAllBytes(filePath));
|
||
// string tmpPath = filePath;
|
||
// File.WriteAllBytes(tmpPath, B83.Image.PNGTools.ChangePPI(bytes, 300, 300));
|
||
// return tmpPath;
|
||
}
|
||
|
||
Texture2D ToTexture2D(RenderTexture rTex)
|
||
{
|
||
RenderTexture currentActiveRT = RenderTexture.active;
|
||
Texture2D tex = new Texture2D(rTex.width, rTex.height, TextureFormat.ARGB32, false);
|
||
RenderTexture.active = rTex;
|
||
tex.ReadPixels(new Rect(0, 0, rTex.width, rTex.height), 0, 0);
|
||
tex.Apply();
|
||
RenderTexture.active = currentActiveRT;
|
||
return tex;
|
||
}
|
||
|
||
IEnumerator WaitCutBG(string filePath, string transferPath)
|
||
{
|
||
string currentDirectory = Directory.GetCurrentDirectory();
|
||
string savePath = Path.Combine(currentDirectory, "temp");
|
||
if (!Directory.Exists(savePath))
|
||
{
|
||
Directory.CreateDirectory(savePath);
|
||
}
|
||
|
||
string fileName = "downloadedTexture.png";
|
||
string transferName = "transferTexture.png";
|
||
string path1 = Path.Combine(savePath, fileName);
|
||
File.Copy(filePath, path1, true);
|
||
string path2 = Path.Combine(savePath, transferName);
|
||
|
||
Debug.Log($"file path: {path1}");
|
||
Debug.Log($"transfer path: {path2}");
|
||
|
||
var startInfo = new System.Diagnostics.ProcessStartInfo
|
||
{
|
||
FileName = "python",
|
||
Arguments = $"cutbg.py \"{path1}\" \"{path2}\"",
|
||
RedirectStandardOutput = true,
|
||
RedirectStandardError = true,
|
||
UseShellExecute = false,
|
||
CreateNoWindow = true
|
||
};
|
||
|
||
System.Diagnostics.Process process = new System.Diagnostics.Process
|
||
{
|
||
StartInfo = startInfo
|
||
};
|
||
Debug.Log("Start");
|
||
process.Start();
|
||
process.WaitForExit();
|
||
// while (!process.HasExited)
|
||
// {
|
||
// yield return null;
|
||
// }
|
||
yield return null;
|
||
}
|
||
} |