FM/Assets/Scripts/FUJIFILM/Other/DoubleCaptureSystem.cs

321 lines
13 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

using UnityEngine;
using System;
using System.Collections;
using System.IO;
using UnityEngine.UI;
using SixLabors.ImageSharp;
using SixLabors.ImageSharp.Formats.Jpeg;
using SixLabors.ImageSharp.Formats.Png;
using SixLabors.ImageSharp.Processing;
namespace HK.FUJIFILM
{
public class DoubleCaptureSystem : TransparentCaptureSystem<DoubleCaptureSystem>
{
/// <summary>
/// 执行两次截图并裁剪,支持分别定制参数
/// </summary>
/// <param name="onBothComplete">两次都完成后的回调(返回两次的字节数组)</param>
public void CaptureTwice(Action<byte[], byte[]> onBothComplete)
{
StartCoroutine(CoCaptureTwice(onBothComplete));
}
public void CaptureOnlyDesign(Action<byte[]> onBothComplete)
{
StartCoroutine(CoCaptureOnlyDesign(onBothComplete));
}
#if UNITY_EDITOR
[ContextMenu("CaptureTwice")]
public void Test()
{
StartCoroutine(CoCaptureTwice(null));
}
#endif
float ConvertMmToPixel(float mm, int dpi = 300)
{
return mm * (dpi / 25.4f);
}
// private void Update()
// {
// if (Input.GetKeyDown(KeyCode.J))
// {
// UnityEngine.Debug.LogError($"px is {ConvertMmToPixel(85.6f)}");
// }
// }
// 协程:顺序执行两次截图
private IEnumerator CoCaptureTwice(Action<byte[], byte[]> onBothComplete)
{
// 存储两次截图的结果
byte[] firstResult = null;
byte[] secondResult = null;
saveFolder = Path.Combine(saveFolder, DateTime.Now.ToString("yyyyMMdd_HHmmss"));
onlyFileName = "PreviewImage1";
var mugActualModelRenderFixed = uiRoot.GetComponent<MugActualModelRender_Fixed>();
var image = mugActualModelRenderFixed.designParent.GetChild(0).GetComponent<UnityEngine.UI.Image>();
image.enabled = true;
// 第一次截图(使用基类默认参数)
Debug.Log("开始第一次截图...");
yield return StartCoroutine(CaptureAndCrop((firstBytes) =>
{
firstResult = firstBytes;
Debug.Log("第一次截图完成");
}));
image.enabled = false;
// 确保第一次完成后再执行第二次
if (firstResult == null)
{
Debug.LogError("第一次截图失败,取消第二次");
onBothComplete?.Invoke(null, null);
yield break;
}
bool tmpImageActive = image.enabled;
image.enabled = mugActualModelRenderFixed.productScriptableObject.isShowTemplate;
var verticalLayoutGroup = mugActualModelRenderFixed.designParent.GetComponent<VerticalLayoutGroup>();
verticalLayoutGroup.enabled = true;
var tmpWidth = cropWidth;
var tmpHeight = cropHeight;
var productScriptableObject = mugActualModelRenderFixed.productScriptableObject;
var screenshotSize = productScriptableObject.screenshotSize;
cropWidth = (int)screenshotSize.x;
cropHeight = (int)screenshotSize.y;
cropOffset = new Vector2(0.5f, 0.5f);
onlyFileName = "DesignImage1";
// 第二次截图(使用修改后的参数)
Debug.Log("开始第二次截图...");
yield return StartCoroutine(CaptureAndCrop((secondBytes) =>
{
secondResult = secondBytes;
Debug.Log("第二次截图完成");
}));
image.enabled = tmpImageActive;
// 1. 校验文件是否存在
var fileInfo = new FileInfo(fullPath);
if (!fileInfo.Exists)
{
Debug.LogError($"原始图片不存在:{fullPath}");
secondResult = null;
yield break; // 若在协程中,用 yield break 退出
}
try
{
// 2. 加载图像并校验原始尺寸
using (var sImage = SixLabors.ImageSharp.Image.Load(fileInfo.FullName))
{
// 校验原始图片尺寸是否有效
if (sImage.Width <= 0 || sImage.Height <= 0)
{
Debug.LogError($"加载的图片尺寸无效:宽={sImage.Width}, 高={sImage.Height}");
secondResult = null;
yield break;
}
if (productScriptableObject.printingSize.x != 0)
{
// 3. 校验缩放宽度是否有效
int targetWidth = (int)ConvertMmToPixel(productScriptableObject.printingSize.x);
int targetHeight = (int)ConvertMmToPixel(productScriptableObject.printingSize.y);
if (targetWidth <= 0)
{
Debug.LogError($"缩放宽度无效(必须大于 0{targetWidth}");
// 可选:使用默认宽度(如 200避免错误
targetWidth = 200;
}
// 4. 等比缩放(确保目标尺寸有效)
// sImage.Mutate(x => x.Resize(new ResizeOptions
// {
// Size = new Size(targetWidth, targetHeight), // 高度为0则自动计算
// Mode = ResizeMode.Max,
// Sampler = KnownResamplers.Lanczos3 // 高质量缩放算法
// }));
// 强制缩放
sImage.Mutate(x => x.Resize(targetWidth, targetHeight));
}
// 5. 确保保存目录存在
if (!Directory.Exists(saveFolder))
{
Directory.CreateDirectory(saveFolder); // 自动创建目录
}
// 6. 保存缩放后的图片
var filePath = Path.Combine(saveFolder, "Printing1.png");
sImage.SaveAsPng(filePath, new PngEncoder());
// 7. 校验保存结果并读取字节数组
if (File.Exists(filePath))
{
secondResult = File.ReadAllBytes(filePath);
Debug.Log($"第二次截图缩放后保存至:{filePath}");
}
else
{
Debug.LogError($"图片保存失败,文件不存在:{filePath}");
secondResult = null;
}
}
}
catch (Exception ex)
{
// 捕获所有异常(如图片格式错误、权限问题等)
Debug.LogError($"图片处理失败:{ex.Message}\n{ex.StackTrace}");
secondResult = null;
}
// 恢复原始参数(避免影响后续截图)
verticalLayoutGroup.enabled = false;
cropWidth = tmpWidth;
cropHeight = tmpHeight;
cropOffset = new Vector2(0f, 0f);
image.enabled = false;
// 触发最终回调
onBothComplete?.Invoke(firstResult, secondResult);
}
// 协程:顺序执行一次设计截图
private IEnumerator CoCaptureOnlyDesign(Action<byte[]> onBothComplete)
{
// 存储两次截图的结果
byte[] secondResult = null;
saveFolder = Path.Combine(saveFolder, DateTime.Now.ToString("yyyyMMdd_HHmmss"));
var mugActualModelRenderFixed = uiRoot.GetComponent<MugActualModelRender_Fixed>();
var image = mugActualModelRenderFixed.designParent.GetChild(0).GetComponent<UnityEngine.UI.Image>();
bool tmpImageActive = image.enabled;
image.enabled = mugActualModelRenderFixed.productScriptableObject.isShowTemplate;
var verticalLayoutGroup = mugActualModelRenderFixed.designParent.GetComponent<VerticalLayoutGroup>();
verticalLayoutGroup.enabled = true;
var tmpWidth = cropWidth;
var tmpHeight = cropHeight;
var productScriptableObject = mugActualModelRenderFixed.productScriptableObject;
var screenshotSize = productScriptableObject.screenshotSize;
cropWidth = (int)screenshotSize.x;
cropHeight = (int)screenshotSize.y;
cropOffset = new Vector2(0.5f, 0.5f);
onlyFileName = "DesignImage1";
// 第二次截图(使用修改后的参数)
Debug.Log("开始第二次截图...");
yield return StartCoroutine(CaptureAndCrop((secondBytes) =>
{
secondResult = secondBytes;
Debug.Log("第二次截图完成");
}));
image.enabled = tmpImageActive;
// 1. 校验文件是否存在
var fileInfo = new FileInfo(fullPath);
if (!fileInfo.Exists)
{
Debug.LogError($"原始图片不存在:{fullPath}");
secondResult = null;
yield break; // 若在协程中,用 yield break 退出
}
try
{
// 2. 加载图像并校验原始尺寸
using (var sImage = SixLabors.ImageSharp.Image.Load(fileInfo.FullName))
{
// 校验原始图片尺寸是否有效
if (sImage.Width <= 0 || sImage.Height <= 0)
{
Debug.LogError($"加载的图片尺寸无效:宽={sImage.Width}, 高={sImage.Height}");
secondResult = null;
yield break;
}
if (productScriptableObject.printingSize.x != 0)
{
// 3. 校验缩放宽度是否有效
int targetWidth = (int)ConvertMmToPixel(productScriptableObject.printingSize.x);
int targetHeight = (int)ConvertMmToPixel(productScriptableObject.printingSize.y);
if (targetWidth <= 0)
{
Debug.LogError($"缩放宽度无效(必须大于 0{targetWidth}");
// 可选:使用默认宽度(如 200避免错误
targetWidth = 200;
}
// 4. 等比缩放(确保目标尺寸有效)
// sImage.Mutate(x => x.Resize(new ResizeOptions
// {
// Size = new Size(targetWidth, targetHeight), // 高度为0则自动计算
// Mode = ResizeMode.Max,
// Sampler = KnownResamplers.Lanczos3 // 高质量缩放算法
// }));
// 强制缩放
sImage.Mutate(x => x.Resize(targetWidth, targetHeight));
}
// 5. 确保保存目录存在
if (!Directory.Exists(saveFolder))
{
Directory.CreateDirectory(saveFolder); // 自动创建目录
}
// 6. 保存缩放后的图片
var filePath = Path.Combine(saveFolder, "Printing1.png");
sImage.SaveAsPng(filePath, new PngEncoder());
// 7. 校验保存结果并读取字节数组
if (File.Exists(filePath))
{
secondResult = File.ReadAllBytes(filePath);
Debug.Log($"第二次截图缩放后保存至:{filePath}");
}
else
{
Debug.LogError($"图片保存失败,文件不存在:{filePath}");
secondResult = null;
}
}
}
catch (Exception ex)
{
// 捕获所有异常(如图片格式错误、权限问题等)
Debug.LogError($"图片处理失败:{ex.Message}\n{ex.StackTrace}");
secondResult = null;
}
// 恢复原始参数(避免影响后续截图)
verticalLayoutGroup.enabled = false;
cropWidth = tmpWidth;
cropHeight = tmpHeight;
cropOffset = new Vector2(0f, 0f);
image.enabled = false;
// 触发最终回调
onBothComplete?.Invoke(secondResult);
}
// 可选:重写基类的立即截图方法,使其默认执行两次
// public override void CaptureAndCropNow(Action<byte[]> callback = null)
// {
// base.CaptureAndCropNow(callback);
// // // 如果需要点击按钮时默认执行两次可在这里调用CaptureTwice
// // CaptureTwice((first, second) =>
// // {
// // callback?.Invoke(first); // 这里仅返回第一次的结果,或按需处理
// // });
// }
}
}