using System; using System.IO; using Cysharp.Threading.Tasks; using UnityEngine; namespace ZXL.Helper { public static class TextureHelper { /// /// 精灵图片转纹理 /// /// /// public static Texture2D SpriteToTexture2D(Sprite sprite) { // 获取 Sprite 的纹理 Texture2D texture = sprite.texture; // 创建一个新的 Texture2D 用于存储 Sprite 的图像数据 Texture2D texture2D = new Texture2D((int)sprite.rect.width, (int)sprite.rect.height); // 读取 Sprite 的像素数据到新的 Texture2D Color[] pixels = texture.GetPixels( (int)sprite.rect.x, (int)sprite.rect.y, (int)sprite.rect.width, (int)sprite.rect.height ); // 将像素数据设置到新的 Texture2D 中 texture2D.SetPixels(pixels); texture2D.Apply(); // 应用更改 return texture2D; } /// /// 纹理转精灵图片 /// /// /// public static Sprite SpriteFromTexture2D(Texture2D texture) { Sprite sprite = Sprite.Create(texture, new Rect(0, 0, texture.width, texture.height), new Vector2(0.5f, 0.5f)); return sprite; } /// /// 截取相机画面并返回纹理图片 /// /// /// public static Texture2D SaveCameraToTexture(Camera camera, bool generateMipMaps = false, TextureFormat textureFormat = TextureFormat.RGBA32) { if (camera == null) { Debug.LogError("Camera is null!"); return null; } RenderTexture originalTargetTexture = camera.targetTexture; RenderTexture tempRenderTexture = null; Texture2D capturedImage = null; try { // 创建临时RenderTexture tempRenderTexture = RenderTexture.GetTemporary( camera.pixelWidth, camera.pixelHeight, 24, RenderTextureFormat.Default); // 设置相机渲染到临时RenderTexture camera.targetTexture = tempRenderTexture; // 强制相机渲染一帧 camera.Render(); // 创建Texture2D capturedImage = new Texture2D( tempRenderTexture.width, tempRenderTexture.height, textureFormat, generateMipMaps); // 保存当前激活的RenderTexture RenderTexture previousActive = RenderTexture.active; // 设置临时RenderTexture为当前激活的,以便读取像素 RenderTexture.active = tempRenderTexture; // 读取像素并应用 capturedImage.ReadPixels(new Rect(0, 0, tempRenderTexture.width, tempRenderTexture.height), 0, 0); capturedImage.Apply(); // 恢复之前的RenderTexture RenderTexture.active = previousActive; } catch (System.Exception e) { Debug.LogError($"Error capturing camera: {e.Message}"); if (capturedImage != null) { UnityEngine.Object.DestroyImmediate(capturedImage); capturedImage = null; } } finally { // 恢复相机的原始设置 camera.targetTexture = originalTargetTexture; // 释放临时RenderTexture if (tempRenderTexture != null) { RenderTexture.ReleaseTemporary(tempRenderTexture); tempRenderTexture = null; } } return capturedImage; } /// /// Texture转Texture2D /// /// /// public static Texture2D ConvertTextureToTexture2D(Texture texture) { Texture2D texture2D = new Texture2D(texture.width, texture.height, TextureFormat.RGBA32, false); RenderTexture currentRT = RenderTexture.active; // 创建一个新的 RenderTexture RenderTexture renderTexture = RenderTexture.GetTemporary(texture.width, texture.height, 32); Graphics.Blit(texture, renderTexture); // 将 RenderTexture 内容复制到 Texture2D RenderTexture.active = renderTexture; texture2D.ReadPixels(new Rect(0, 0, renderTexture.width, renderTexture.height), 0, 0); texture2D.Apply(); // 清理 RenderTexture.active = currentRT; RenderTexture.ReleaseTemporary(renderTexture); return texture2D; } /// /// 纹理图片转二进制数据 /// /// /// public static byte[] ConvertTextureToByteArray(Texture2D texture) { return texture.EncodeToPNG(); } /// /// 二进制数据转纹理图片 /// /// /// public static Texture2D ConvertByteArrayToTexture2D(byte[] bytes) { Texture2D texture = new Texture2D(2, 2); // 初始化一个临时的 Texture2D if (texture.LoadImage(bytes)) // 使用 LoadImage 来加载字节数据 { return texture; } else { Debug.LogError("加载图片失败!"); return null; } } public static async UniTask TransparentCaptureSystem(TransparentCaptureSystemOption option) { /* if (option.targetCamera == null) { throw new NullReferenceException("targetCamera is null"); return; } async UniTask CaptureAndCrop() { // 确保尺寸有效 ValidateSizes(); // 创建原始截图 await (CaptureOriginalScreenshot()); // 裁剪图片(保留透明通道) CropWithTransparency(); // 保存结果 SaveCroppedImage(); // 清理资源 CleanupResources(); } async UniTask CaptureOriginalScreenshot() { // 创建RenderTexture(带alpha通道) option._renderTexture = new RenderTexture(option.captureWidth, option.captureHeight, 32, RenderTextureFormat.ARGB32); option._renderTexture.Create(); // 保存原始相机设置 RenderTexture originalRT = option.targetCamera.targetTexture; CameraClearFlags originalClearFlags = option.targetCamera.clearFlags; Color originalBackgroundColor = option.targetCamera.backgroundColor; // 配置相机透明背景 option.targetCamera.targetTexture = option._renderTexture; option.targetCamera.clearFlags = CameraClearFlags.SolidColor; option.targetCamera.backgroundColor = option.preserveAlpha ? option.backgroundColor : Color.black; // 渲染相机 option.targetCamera.Render(); // 创建Texture2D(带alpha通道) option._originalTexture = new Texture2D(option.captureWidth, option.captureHeight, option.preserveAlpha ? TextureFormat.ARGB32 : TextureFormat.RGB24, false); // 读取像素(包括alpha) RenderTexture.active = option._renderTexture; option._originalTexture.ReadPixels(new Rect(0, 0, option.captureWidth, option.captureHeight), 0, 0); option._originalTexture.Apply(); RenderTexture.active = null; // 恢复相机设置 option.targetCamera.targetTexture = originalRT; option.targetCamera.clearFlags = originalClearFlags; option.targetCamera.backgroundColor = originalBackgroundColor; } string fullPath; void CropWithTransparency() { if (option._originalTexture == null) { Debug.LogError("原始截图未创建!"); return; } // 计算裁剪起始位置 int startX = Mathf.FloorToInt((option._originalTexture.width - option.cropWidth) * option.cropOffset.x); int startY = Mathf.FloorToInt((option._originalTexture.height - option.cropHeight) * option.cropOffset.y); // 确保在有效范围内 startX = Mathf.Clamp(startX, 0, option._originalTexture.width - option.cropWidth); startY = Mathf.Clamp(startY, 0, option._originalTexture.height - option.cropHeight); // 创建裁剪后的纹理(带alpha通道) option._croppedTexture = new Texture2D(option.cropWidth, option.cropHeight, option.preserveAlpha ? TextureFormat.ARGB32 : TextureFormat.RGB24, false); // 获取原始纹理的像素数据(包括alpha) Color[] pixels = option._originalTexture.GetPixels(startX, startY, option.cropWidth, option.cropHeight); // 设置到裁剪纹理 option._croppedTexture.SetPixels(pixels); option._croppedTexture.Apply(); } void SaveCroppedImage() { if (option._croppedTexture == null) { Debug.LogError("裁剪后的纹理未创建!"); return; } // 创建保存目录 string folderPath = option.saveFolder; if (!Directory.Exists(folderPath)) Directory.CreateDirectory(folderPath); // 生成文件名 string timestamp = DateTime.Now.ToString("yyyyMMdd_HHmmss"); string extension = option.saveAsPNG ? ".png" : ".jpg"; string fileName; if (string.IsNullOrEmpty(option.onlyFileName)) fileName = $"{option.fileNamePrefix}_{option.cropWidth}x{option.cropHeight}_{timestamp}{extension}"; else fileName = $"{option.onlyFileName}{extension}"; fullPath = Path.Combine(folderPath, fileName); // 编码保存 byte[] imageBytes; if (option.saveAsPNG) { imageBytes = option._croppedTexture.EncodeToPNG(); } else { // JPG不支持透明通道,强制去除alpha Texture2D jpgTexture = new Texture2D(option._croppedTexture.width, option._croppedTexture.height, TextureFormat.RGB24, false); jpgTexture.SetPixels(option._croppedTexture.GetPixels()); jpgTexture.Apply(); imageBytes = jpgTexture.EncodeToJPG(90); } File.WriteAllBytes(fullPath, imageBytes); // 验证透明度 if (option.saveAsPNG && option.preserveAlpha) { // 检查左上角像素是否透明 Color topLeft = option._croppedTexture.GetPixel(0, option._croppedTexture.height - 1); Debug.Log($"保存的图片左上角透明度: {topLeft.a}"); // 检查中心像素是否透明 Color center = option._croppedTexture.GetPixel(option._croppedTexture.width / 2, option._croppedTexture.height / 2); Debug.Log($"保存的图片中心透明度: {center.a}"); } Debug.Log($"截图已保存至: {fullPath}"); #if UNITY_EDITOR UnityEditor.EditorUtility.RevealInFinder(fullPath); #endif } void ValidateSizes() { // 确保原始尺寸有效 option.captureWidth = Mathf.Clamp(option.captureWidth, 32, SystemInfo.maxTextureSize); option. captureHeight = Mathf.Clamp(option.captureHeight, 32, SystemInfo.maxTextureSize); // 确保裁剪尺寸有效 option.cropWidth = Mathf.Clamp(option.cropWidth, 32,option. captureWidth); option.cropHeight = Mathf.Clamp(option.cropHeight, 32, option.captureHeight); // 确保偏移量在0-1范围 option.cropOffset.x = Mathf.Clamp01(option.cropOffset.x); option.cropOffset.y = Mathf.Clamp01(option.cropOffset.y); } void CleanupResources() { if (option._renderTexture != null) { Destroy(_renderTexture); option._renderTexture = null; } if (option._originalTexture != null) { Destroy(_originalTexture); option._originalTexture = null; } // 保留裁剪纹理用于预览或后续使用 // 如果不再需要,可以取消注释下面一行 Destroy(_croppedTexture); } UniTask.Run(CaptureAndCrop); */ } } public class TransparentCaptureSystemOption { // 相机设置 public Camera targetCamera; public KeyCode captureKey = KeyCode.C; // 原始截图设置 public int captureWidth = 1080; public int captureHeight = 1920; // 裁剪设置 public int cropWidth = 800; public int cropHeight = 300; public Vector2 cropOffset = Vector2.zero; // 裁剪偏移量 (0-1) // 透明通道 public bool preserveAlpha = true; public Color backgroundColor = new Color(0, 0, 0, 0); // 透明背景 // 输出设置 public string saveFolder = "Screenshots"; public string fileNamePrefix = "Screenshot"; public bool saveAsPNG = true; public string onlyFileName = ""; public RenderTexture _renderTexture; public Texture2D _originalTexture; public Texture2D _croppedTexture; } }