2025-08-20 11:14:21 +08:00
|
|
|
|
using UnityEngine;
|
|
|
|
|
using UnityEngine.UI;
|
|
|
|
|
|
|
|
|
|
namespace HK.FUJIFILM
|
|
|
|
|
{
|
2025-08-27 01:05:19 +08:00
|
|
|
|
public static class RawImageScaler
|
|
|
|
|
{
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 将Texture2D赋值给RawImage并确保等比缩放,保持在RawImage最大范围内
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="rawImage">目标RawImage组件</param>
|
|
|
|
|
/// <param name="texture">要显示的Texture2D</param>
|
|
|
|
|
/// <param name="maxWidth">最大宽度限制(若为0则使用RawImage的当前宽度)</param>
|
|
|
|
|
/// <param name="maxHeight">最大高度限制(若为0则使用RawImage的当前高度)</param>
|
|
|
|
|
public static void SetTextureWithAspectRatio(RawImage rawImage, Texture2D texture, float maxWidth = 0,
|
|
|
|
|
float maxHeight = 0)
|
|
|
|
|
{
|
|
|
|
|
if (rawImage == null || texture == null)
|
|
|
|
|
{
|
|
|
|
|
Debug.LogError("RawImage或Texture2D不能为空");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 赋值纹理
|
|
|
|
|
rawImage.texture = texture;
|
|
|
|
|
|
|
|
|
|
// 获取纹理原始宽高
|
|
|
|
|
float textureWidth = texture.width;
|
|
|
|
|
float textureHeight = texture.height;
|
|
|
|
|
|
|
|
|
|
// 如果未指定最大宽高,使用RawImage当前的尺寸作为限制
|
|
|
|
|
float limitWidth = maxWidth > 0 ? maxWidth : rawImage.rectTransform.rect.width;
|
|
|
|
|
float limitHeight = maxHeight > 0 ? maxHeight : rawImage.rectTransform.rect.height;
|
|
|
|
|
|
|
|
|
|
// 计算宽高比例
|
|
|
|
|
float textureAspect = textureWidth / textureHeight;
|
|
|
|
|
float limitAspect = limitWidth / limitHeight;
|
|
|
|
|
|
|
|
|
|
// 计算缩放后的尺寸(保持比例并适应限制范围)
|
|
|
|
|
float scaledWidth, scaledHeight;
|
|
|
|
|
|
|
|
|
|
if (textureAspect > limitAspect)
|
|
|
|
|
{
|
|
|
|
|
// 纹理更宽,按宽度限制缩放
|
|
|
|
|
scaledWidth = limitWidth;
|
|
|
|
|
scaledHeight = scaledWidth / textureAspect;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
// 纹理更高或比例相同,按高度限制缩放
|
|
|
|
|
scaledHeight = limitHeight;
|
|
|
|
|
scaledWidth = scaledHeight * textureAspect;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 应用缩放后的尺寸
|
|
|
|
|
rawImage.rectTransform.sizeDelta = new Vector2(scaledWidth, scaledHeight);
|
|
|
|
|
|
|
|
|
|
// 可选:居中显示
|
|
|
|
|
rawImage.rectTransform.anchorMin = new Vector2(0.5f, 0.5f);
|
|
|
|
|
rawImage.rectTransform.anchorMax = new Vector2(0.5f, 0.5f);
|
|
|
|
|
rawImage.rectTransform.pivot = new Vector2(0.5f, 0.5f);
|
|
|
|
|
rawImage.rectTransform.anchoredPosition = Vector2.zero;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-08-20 11:14:21 +08:00
|
|
|
|
public static class ImageScaler
|
|
|
|
|
{
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 将Image等比缩放到不超过指定的最大尺寸(宽和高中较大的值不超过maxSize)
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="image">需要缩放的Image组件</param>
|
|
|
|
|
/// <param name="maxSize">宽和高中较大值的最大限制</param>
|
|
|
|
|
/// <param name="keepOriginalIfSmaller">如果原图比限制小,是否保持原图大小</param>
|
2025-08-27 01:05:19 +08:00
|
|
|
|
public static void ScaleImageWithSize(Image image, float maxSize, bool keepOriginalIfSmaller = false)
|
|
|
|
|
{
|
|
|
|
|
if (image == null)
|
|
|
|
|
{
|
|
|
|
|
Debug.LogError("Image组件不能为空!");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 获取原始尺寸
|
|
|
|
|
float originalWidth, originalHeight;
|
|
|
|
|
|
|
|
|
|
if (image.sprite != null)
|
|
|
|
|
{
|
|
|
|
|
// 使用Sprite的原始尺寸
|
|
|
|
|
originalWidth = image.sprite.rect.width;
|
|
|
|
|
originalHeight = image.sprite.rect.height;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
// 没有Sprite时使用当前RectTransform的尺寸
|
|
|
|
|
originalWidth = image.rectTransform.rect.width;
|
|
|
|
|
originalHeight = image.rectTransform.rect.height;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 计算缩放比例
|
|
|
|
|
float scaleRatio = CalculateScaleRatio(originalWidth, originalHeight, maxSize, keepOriginalIfSmaller);
|
|
|
|
|
|
|
|
|
|
// 应用缩放后的尺寸
|
|
|
|
|
image.rectTransform.sizeDelta = new Vector2(
|
|
|
|
|
originalWidth,
|
|
|
|
|
originalHeight
|
|
|
|
|
);
|
|
|
|
|
// image.rectTransform.sizeDelta = new Vector2(
|
|
|
|
|
// originalWidth * scaleRatio,
|
|
|
|
|
// originalHeight * scaleRatio
|
|
|
|
|
// );
|
|
|
|
|
}
|
|
|
|
|
|
2025-08-20 11:14:21 +08:00
|
|
|
|
public static void ScaleImageWithMaxSize(Image image, float maxSize, bool keepOriginalIfSmaller = false)
|
|
|
|
|
{
|
|
|
|
|
if (image == null)
|
|
|
|
|
{
|
|
|
|
|
Debug.LogError("Image组件不能为空!");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 获取原始尺寸
|
|
|
|
|
float originalWidth, originalHeight;
|
2025-08-27 01:05:19 +08:00
|
|
|
|
|
2025-08-20 11:14:21 +08:00
|
|
|
|
if (image.sprite != null)
|
|
|
|
|
{
|
|
|
|
|
// 使用Sprite的原始尺寸
|
|
|
|
|
originalWidth = image.sprite.rect.width;
|
|
|
|
|
originalHeight = image.sprite.rect.height;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
// 没有Sprite时使用当前RectTransform的尺寸
|
|
|
|
|
originalWidth = image.rectTransform.rect.width;
|
|
|
|
|
originalHeight = image.rectTransform.rect.height;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 计算缩放比例
|
|
|
|
|
float scaleRatio = CalculateScaleRatio(originalWidth, originalHeight, maxSize, keepOriginalIfSmaller);
|
|
|
|
|
|
|
|
|
|
// 应用缩放后的尺寸
|
|
|
|
|
image.rectTransform.sizeDelta = new Vector2(
|
|
|
|
|
originalWidth * scaleRatio,
|
|
|
|
|
originalHeight * scaleRatio
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 计算缩放比例
|
|
|
|
|
/// </summary>
|
2025-08-27 01:05:19 +08:00
|
|
|
|
private static float CalculateScaleRatio(float originalWidth, float originalHeight, float maxSize,
|
|
|
|
|
bool keepOriginalIfSmaller)
|
2025-08-20 11:14:21 +08:00
|
|
|
|
{
|
|
|
|
|
// 找到原始宽高中的较大值
|
|
|
|
|
float maxOriginal = Mathf.Max(originalWidth, originalHeight);
|
|
|
|
|
|
|
|
|
|
// 如果原图的最大边小于等于限制值,且需要保持原图大小,则不缩放
|
|
|
|
|
if (maxOriginal <= maxSize && keepOriginalIfSmaller)
|
|
|
|
|
{
|
|
|
|
|
return 1f; // 不缩放
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 计算缩放比例(让最大边刚好等于maxSize)
|
|
|
|
|
return maxSize / maxOriginal;
|
|
|
|
|
}
|
2025-09-07 11:22:38 +08:00
|
|
|
|
|
2025-08-28 23:32:43 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// 保持Image的sizeDelta为原始图片尺寸,仅通过修改scale来限制最大显示大小
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="image">目标Image组件</param>
|
|
|
|
|
/// <param name="maxSize">最大显示尺寸(图片的宽或高中较大者不会超过此值)</param>
|
|
|
|
|
/// <param name="keepOriginalIfSmaller">如果原始尺寸小于maxSize,是否保持原始大小</param>
|
|
|
|
|
public static void ScaleImageWithMaxSize_Scale(Image image, float maxSize, bool keepOriginalIfSmaller = false)
|
|
|
|
|
{
|
|
|
|
|
if (image == null)
|
|
|
|
|
{
|
|
|
|
|
Debug.LogError("Image组件不能为空!");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 获取原始图片尺寸(像素尺寸)
|
|
|
|
|
float originalWidth, originalHeight;
|
|
|
|
|
|
|
|
|
|
if (image.sprite != null)
|
|
|
|
|
{
|
|
|
|
|
// 使用Sprite的原始像素尺寸
|
|
|
|
|
originalWidth = image.sprite.rect.width;
|
|
|
|
|
originalHeight = image.sprite.rect.height;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
// 没有Sprite时使用当前RectTransform的尺寸作为原始尺寸
|
|
|
|
|
originalWidth = image.rectTransform.rect.width;
|
|
|
|
|
originalHeight = image.rectTransform.rect.height;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 将sizeDelta设置为原始图片尺寸(保持像素尺寸不变)
|
|
|
|
|
image.rectTransform.sizeDelta = new Vector2(originalWidth, originalHeight);
|
|
|
|
|
|
|
|
|
|
// 计算缩放比例
|
|
|
|
|
float scaleRatio = CalculateScaleRatio_Scale(originalWidth, originalHeight, maxSize, keepOriginalIfSmaller);
|
|
|
|
|
|
|
|
|
|
// 仅修改scale来限制最大显示大小
|
|
|
|
|
image.rectTransform.localScale = Vector3.one * scaleRatio;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 计算缩放比例
|
|
|
|
|
/// </summary>
|
2025-09-07 11:22:38 +08:00
|
|
|
|
private static float CalculateScaleRatio_Scale(float width, float height, float maxSize,
|
|
|
|
|
bool keepOriginalIfSmaller)
|
2025-08-28 23:32:43 +08:00
|
|
|
|
{
|
|
|
|
|
if (width <= 0 || height <= 0) return 1f;
|
|
|
|
|
|
|
|
|
|
// 计算原始尺寸中较大的一边
|
|
|
|
|
float maxDimension = Mathf.Max(width, height);
|
|
|
|
|
|
|
|
|
|
// 如果原始尺寸小于maxSize且需要保持原始大小,则不缩放
|
|
|
|
|
if (maxDimension <= maxSize && keepOriginalIfSmaller)
|
|
|
|
|
{
|
|
|
|
|
return 1f;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 计算缩放比例(确保最大边不超过maxSize)
|
|
|
|
|
return maxSize / maxDimension;
|
|
|
|
|
}
|
2025-09-07 11:22:38 +08:00
|
|
|
|
|
|
|
|
|
public static void ScaleImageWithMinSize(Image image, float minSize, bool keepOriginalIfLarger = false)
|
|
|
|
|
{
|
|
|
|
|
Debug.Log(minSize);
|
|
|
|
|
if (image == null)
|
|
|
|
|
{
|
|
|
|
|
Debug.LogError("Image组件不能为空!");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 获取原始图片尺寸(像素尺寸)
|
|
|
|
|
float originalWidth, originalHeight;
|
|
|
|
|
|
|
|
|
|
if (image.sprite != null)
|
|
|
|
|
{
|
|
|
|
|
// 使用Sprite的原始像素尺寸
|
|
|
|
|
originalWidth = image.sprite.rect.width;
|
|
|
|
|
originalHeight = image.sprite.rect.height;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
// 没有Sprite时使用当前RectTransform的尺寸作为原始尺寸
|
|
|
|
|
originalWidth = image.rectTransform.rect.width;
|
|
|
|
|
originalHeight = image.rectTransform.rect.height;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 将sizeDelta设置为原始图片尺寸(保持像素尺寸不变)
|
|
|
|
|
image.rectTransform.sizeDelta = new Vector2(originalWidth, originalHeight);
|
|
|
|
|
|
|
|
|
|
// 计算缩放比例
|
|
|
|
|
float scaleRatio = CalculateScaleRatio_Min(originalWidth, originalHeight, minSize, keepOriginalIfLarger);
|
|
|
|
|
|
|
|
|
|
// 应用缩放比例
|
|
|
|
|
image.rectTransform.localScale = Vector3.one * scaleRatio;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 计算缩放到最小尺寸的比例
|
|
|
|
|
/// </summary>
|
|
|
|
|
private static float CalculateScaleRatio_Min(float width, float height, float minSize,
|
|
|
|
|
bool keepOriginalIfLarger)
|
|
|
|
|
{
|
|
|
|
|
if (width <= 0 || height <= 0) return 1f;
|
|
|
|
|
|
|
|
|
|
// 计算原始尺寸中较小的一边
|
|
|
|
|
float minDimension = Mathf.Min(width, height);
|
|
|
|
|
|
|
|
|
|
// 如果原始尺寸大于minSize且需要保持原始大小,则不缩放
|
|
|
|
|
if (minDimension >= minSize && keepOriginalIfLarger)
|
|
|
|
|
{
|
|
|
|
|
return 1f;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 计算缩放比例(确保最小边不小于minSize)
|
|
|
|
|
return minSize / minDimension;
|
|
|
|
|
}
|
2025-08-20 11:14:21 +08:00
|
|
|
|
}
|
|
|
|
|
}
|