using Sirenix.OdinInspector; using UnityEngine; using UnityEngine.UI; namespace System.Utils { [AddComponentMenu ("UI/Tools/ImageAdaptiveCropper")] [RequireComponent (typeof(Image))] public class ImageAdaptiveCropper : MonoBehaviour { // private bool _hasHorizontal; [SerializeField] private Image _image; private RectTransform _rectTransform; private Texture2D _texture2D; #if UNITY_EDITOR [SerializeField] private Texture2D _preview; [Button ("测试")] private void PreviewAdjust () { SetAdjustTexture (this._preview); } #endif public Image Image { get { if (this._image == null) { this._image = this.GetComponent (); } return this._image; } } private RectTransform RectTransform { get { if (this._rectTransform == null) { this._rectTransform = this.Image.transform as RectTransform; } return this._rectTransform; } } public Texture2D Texture2D { get => this._texture2D; // set => SetTexture (value); } public void SetAdjustTexture (Texture2D texture) { if (texture == null) return; var imageSize = this.RectTransform.sizeDelta; if (imageSize.x == 0 || imageSize.y == 0) return; var imageWidth = Mathf.Abs ((imageSize.x)); var imageHeight = Mathf.Abs ((imageSize.y)); var texture2DHeight = texture.height; var texture2DWidth = texture.width; var newWidth = 0f; var newHeight = 0f; if (imageWidth / imageHeight > texture2DWidth * 1f / texture2DHeight) { newHeight = texture2DWidth * (imageHeight / imageWidth); newWidth = newHeight * (imageWidth / imageHeight); if (newWidth > texture2DWidth) { var widthExOffset = newWidth / texture2DWidth; newWidth = texture2DWidth; newHeight = newHeight * (1 - widthExOffset); } } else { newWidth = texture2DHeight * (imageWidth / imageHeight); newHeight = newWidth * (imageHeight / imageWidth); if (newHeight > texture2DHeight) { var heightExOffset = newHeight / texture2DHeight; newHeight = texture2DHeight; newWidth = newWidth * (1 - heightExOffset); } } var offsetX = Mathf.FloorToInt ((texture2DWidth - newWidth) * 0.5f); var offsetY = Mathf.FloorToInt ((texture2DHeight - newHeight) * 0.5f); var textureCutOut = TextureCutOut (texture , offsetX , offsetY , newWidth , newHeight); this._texture2D = textureCutOut; this.Image.sprite = Sprite.Create (this._texture2D , new Rect (0 , 0 , this._texture2D.width , this._texture2D.height) , new Vector2 (0.5f , 0.5f)); } public void SetTexture (Sprite sprite) { // this._texture2D = sprite.texture; this.Image.sprite = sprite; } public void SetTextureAndAdjust (Sprite texture , Vector2 maskSize) { SetTexture (texture); // AdjustImage (maskSize); } public void AdjustImage (Vector2 maskSize) { var imageSize = maskSize; if (imageSize.x == 0 || imageSize.y == 0) return; var imageWidth = Mathf.Abs ((imageSize.x)); var imageHeight = Mathf.Abs ((imageSize.y)); var texture2DHeight = this._texture2D.height; var texture2DWidth = this._texture2D.width; var rota = texture2DWidth * 1f / texture2DHeight; if (imageWidth / imageHeight > rota) { this.RectTransform.sizeDelta = new Vector2 (imageWidth , imageWidth / rota); } else { this.RectTransform.sizeDelta = new Vector2 (imageHeight * rota, imageHeight); } this.RectTransform.anchoredPosition = Vector2.zero; } private Texture2D TextureCutOut (Texture2D originalTexture, int offsetX, int offsetY, float originalWidth, float originalHeight) { // originalTexture. Texture2D newTexture = new Texture2D (Mathf.CeilToInt (originalWidth), Mathf.CeilToInt (originalHeight)); var pixels = originalTexture.GetPixels (); var originalTextureWidth = originalTexture.width; var originalTextureHeight = originalTexture.height; var colorList = new Color[newTexture.width * newTexture.height]; for (int y = 0; y < newTexture.height; y++) { for (int x = 0; x < newTexture.width; x++) { newTexture.SetPixel (x, y, originalTexture.GetPixel (x + offsetX , y + offsetY)); // var color = pixels[(y + offsetY) * originalTextureWidth + (x + offsetX)]; // colorList[x * y] = color; } } newTexture.SetPixels (colorList); newTexture.anisoLevel = 2; newTexture.Apply (); return newTexture; } } }