159 lines
5.7 KiB
C#
159 lines
5.7 KiB
C#
using System;
|
|
using System.IO;
|
|
using Rive.Utils;
|
|
using UnityEditor;
|
|
using UnityEngine;
|
|
|
|
namespace Rive
|
|
{
|
|
/// <summary>
|
|
/// Custom editor for ImageOutOfBandAsset that displays a preview of the image.
|
|
/// </summary>
|
|
[CustomEditor(typeof(ImageOutOfBandAsset))]
|
|
public class ImageOutOfBandAssetEditor : Editor
|
|
{
|
|
private enum PreviewMode
|
|
{
|
|
Contain = 0,
|
|
Cover = 1
|
|
}
|
|
|
|
private PreviewMode previewMode = PreviewMode.Contain;
|
|
public override Texture2D RenderStaticPreview(string assetPath, UnityEngine.Object[] subAssets, int width, int height)
|
|
{
|
|
var asset = (ImageOutOfBandAsset)target;
|
|
|
|
if (asset == null || asset.Bytes == null || asset.Bytes.Length == 0)
|
|
{
|
|
return null;
|
|
}
|
|
// WebP images are not currently supported for previews because they are not natively supported by the Unity engine, custom support will be added in the future.
|
|
if (IsWebp(assetPath))
|
|
{
|
|
return null;
|
|
}
|
|
|
|
Texture2D originalTexture = LoadOriginalTexture(asset.Bytes);
|
|
if (originalTexture == null)
|
|
{
|
|
return null;
|
|
}
|
|
|
|
Vector2Int newSize = CalculateNewSize(originalTexture.width, originalTexture.height, width, height);
|
|
Texture2D resizedTexture = ResizeTexture(originalTexture, newSize.x, newSize.y);
|
|
Texture2D previewTexture = CreatePreviewTexture(resizedTexture, width, height);
|
|
|
|
UnityEngine.Object.DestroyImmediate(originalTexture);
|
|
UnityEngine.Object.DestroyImmediate(resizedTexture);
|
|
|
|
return previewTexture;
|
|
}
|
|
|
|
private Texture2D LoadOriginalTexture(byte[] bytes)
|
|
{
|
|
Texture2D texture = new Texture2D(2, 2);
|
|
if (texture.LoadImage(bytes))
|
|
{
|
|
return texture;
|
|
}
|
|
|
|
DebugLogger.Instance.LogWarning("Failed to load image preview for ImageOutOfBandAsset");
|
|
|
|
return null;
|
|
}
|
|
|
|
private Vector2Int CalculateNewSize(int originalWidth, int originalHeight, int targetWidth, int targetHeight)
|
|
{
|
|
float aspectRatio = (float)originalWidth / originalHeight;
|
|
float targetAspectRatio = (float)targetWidth / targetHeight;
|
|
|
|
switch (previewMode)
|
|
{
|
|
case PreviewMode.Contain:
|
|
if (targetAspectRatio > aspectRatio)
|
|
{
|
|
return new Vector2Int(
|
|
Mathf.RoundToInt(targetHeight * aspectRatio),
|
|
targetHeight
|
|
);
|
|
}
|
|
else
|
|
{
|
|
return new Vector2Int(
|
|
targetWidth,
|
|
Mathf.RoundToInt(targetWidth / aspectRatio)
|
|
);
|
|
}
|
|
|
|
case PreviewMode.Cover:
|
|
if (targetAspectRatio > aspectRatio)
|
|
{
|
|
return new Vector2Int(
|
|
targetWidth,
|
|
Mathf.RoundToInt(targetWidth / aspectRatio)
|
|
);
|
|
}
|
|
else
|
|
{
|
|
return new Vector2Int(
|
|
Mathf.RoundToInt(targetHeight * aspectRatio),
|
|
targetHeight
|
|
);
|
|
}
|
|
default:
|
|
DebugLogger.Instance.LogWarning($"Unsupported preview mode: {previewMode}. Falling back to Contain mode.");
|
|
goto case PreviewMode.Contain;
|
|
}
|
|
}
|
|
|
|
private Texture2D ResizeTexture(Texture2D originalTexture, int newWidth, int newHeight)
|
|
{
|
|
RenderTexture rt = RenderTexture.GetTemporary(newWidth, newHeight, 0, RenderTextureFormat.Default, RenderTextureReadWrite.Linear);
|
|
|
|
// Set the filter mode to bilinear to match the previous scaling method
|
|
rt.filterMode = FilterMode.Bilinear;
|
|
|
|
RenderTexture.active = rt;
|
|
Graphics.Blit(originalTexture, rt);
|
|
Texture2D resizedTexture = new Texture2D(newWidth, newHeight);
|
|
resizedTexture.ReadPixels(new Rect(0, 0, newWidth, newHeight), 0, 0);
|
|
resizedTexture.Apply();
|
|
RenderTexture.active = null;
|
|
RenderTexture.ReleaseTemporary(rt);
|
|
|
|
return resizedTexture;
|
|
}
|
|
|
|
private Texture2D CreatePreviewTexture(Texture2D resizedTexture, int width, int height)
|
|
{
|
|
Texture2D previewTexture = new Texture2D(width, height, TextureFormat.RGBA32, false);
|
|
|
|
// Fill the background with transparency
|
|
UnityEngine.Color[] fillPixels = new UnityEngine.Color[width * height];
|
|
for (int i = 0; i < fillPixels.Length; i++)
|
|
fillPixels[i] = UnityEngine.Color.clear;
|
|
previewTexture.SetPixels(fillPixels);
|
|
|
|
// Center the resized image
|
|
int x = (width - resizedTexture.width) / 2;
|
|
int y = (height - resizedTexture.height) / 2;
|
|
|
|
// Copy the resized image to the center of the preview texture
|
|
previewTexture.SetPixels32(x, y, resizedTexture.width, resizedTexture.height, resizedTexture.GetPixels32());
|
|
previewTexture.Apply();
|
|
|
|
return previewTexture;
|
|
}
|
|
|
|
private bool IsWebp(string assetPath)
|
|
{
|
|
if (string.IsNullOrEmpty(assetPath))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
return string.Equals(System.IO.Path.GetExtension(assetPath), ".webp", StringComparison.OrdinalIgnoreCase);
|
|
}
|
|
|
|
}
|
|
} |