using System.Collections; using System.IO; using UnityEngine; using UnityEngine.Networking; using UnityEngine.UI; using Image = UnityEngine.UI.Image; using Color = UnityEngine.Color; using SixLabors.ImageSharp.Processing; using SixLabors.ImageSharp; public class PhotoFrame : MonoBehaviour { [SerializeField] GameObject mainUI; [SerializeField] RectTransform imageContainer; [SerializeField] Image[] images; [SerializeField] InputField url; private int currentImage; private Image CurrentImage { get { return images[currentImage]; } } private Image NextImage { get { return images[(currentImage + 1) % images.Length]; } } public void Start() { currentImage = 0; ActivateUI(true); } private void ActivateUI(bool v) { mainUI.gameObject.SetActive(v); for (int i = 0; i < images.Length; i++) { images[i].gameObject.SetActive(!v); } } Coroutine mainCoroutine; public void OnRunButtonClicked() { ActivateUI(false); mainCoroutine = StartCoroutine(SwitchImages()); } public void OnStopButtonClicked() { if (mainCoroutine != null) { StopCoroutine(mainCoroutine); mainCoroutine = null; } for (int i = 0; i < images.Length; i++) { if (images[i].sprite != null) { Destroy(images[i].sprite.texture); Destroy(images[i].sprite); images[i].sprite = null; } } ActivateUI(true); } private IEnumerator SwitchImages() { yield return null; var loader = new ImageLoader(url.text); while (loader.Status == LoaderStatus.Initializing) yield return null; Color opaque = new Color(1, 1, 1, 1); Color transparent = new Color(1, 1, 1, 0); CurrentImage.color = transparent; NextImage.color = transparent; while (true) { int imageIndex = Random.Range(0, loader.images.Count); string imageUrl = loader.images[imageIndex]; var path = Application.persistentDataPath + "/source." + System.IO.Path.GetExtension(imageUrl); var request = UnityWebRequest.Get(imageUrl); request.downloadHandler = new DownloadHandlerFile(path); yield return request.SendWebRequest(); if (request.isNetworkError || request.isHttpError) { yield return new WaitForSeconds(1f); continue; } SetImageTexture(NextImage, path); request.downloadHandler.Dispose(); request.Dispose(); float currentStart = CurrentImage.color.a; float currentFinish = transparent.a; float nextStart = NextImage.color.a; float nextFinish = opaque.a; float startTime = Time.time; while (Time.time < startTime + 2f) { float ct = Time.time; float x = (ct - startTime) / 2f; float currentA = currentStart + x * (currentFinish - currentStart); Color cC = new Color(CurrentImage.color.r, CurrentImage.color.g, CurrentImage.color.b, currentA); CurrentImage.color = cC; float nextA = nextStart + x * (nextFinish - nextStart); Color nC = new Color(NextImage.color.r, NextImage.color.g, NextImage.color.b, nextA); NextImage.color = nC; yield return null; } yield return new WaitForSeconds(5f); currentImage = (currentImage + 1) % images.Length; Resources.UnloadUnusedAssets(); System.GC.Collect(); } } private void SetImageTexture(Image nextImage, string path) { if (nextImage.sprite != null) { Destroy(nextImage.sprite.texture); Destroy(nextImage.sprite); nextImage.sprite = null; } float imageWidth = imageContainer.rect.width; float imageHeight = imageContainer.rect.height; // int maxHeight, maxWidth; if (imageWidth < imageHeight) { // scale to height maxHeight = 2048; maxWidth = (int)(2048 / imageHeight * imageWidth); } else { // scale to width maxWidth = 2048; maxHeight = (int)(2048 / imageWidth * imageHeight); } Texture2D tex = new Texture2D(2, 2); tex.LoadImage(File.ReadAllBytes(path)); float factor = Mathf.Min((float) maxWidth / tex.width, (float)maxHeight / tex.height); int newWidth = (int)(tex.width * factor); int newHeight = (int)(tex.height * factor); Destroy(tex); var newPath = Scale(path, newWidth, newHeight); tex = new Texture2D(2, 2); tex.LoadImage(File.ReadAllBytes(newPath)); //TextureScale.Bilinear(tex, newWidth, newHeight); //TextureScale.Point(tex, newWidth, newHeight); //Color[] cs = tex.GetPixels(); var sprite = Sprite.Create(tex, new Rect(0, 0, tex.width, tex.height), Vector2.zero); nextImage.sprite = sprite; nextImage.rectTransform.anchorMin = new Vector2((maxWidth - (float)newWidth) / maxWidth / 2, (maxHeight - (float)newHeight) / maxHeight / 2); } private string Scale(string path, int newWidth, int newHeight) { var resultPath = Path.GetDirectoryName(path) + "/target." + Path.GetExtension(path); using (SixLabors.ImageSharp.Image image = SixLabors.ImageSharp.Image.Load(path)) { image.Mutate(x => x.Resize(newWidth, newHeight)); image.Save(resultPath); } return resultPath; } }