Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using System;
- using System.Collections;
- using System.Collections.Generic;
- using UnityEngine;
- using System.IO;
- using BayatGames.SaveGamePro;
- using UnityEngine.UI;
- using System.Drawing;
- public class ScreenShootBase : MonoBehaviour
- {
- // [SerializeField]
- // private UIColorManager uiColorManager;
- [SerializeField]
- private GeometryBuilder geometryBuilder;
- [SerializeField]
- private float previewScale;
- [SerializeField]
- private float mainScale;
- [Range(0, 100)]
- [SerializeField]
- private int offsetX = 5;
- [Range(-100,0)]
- [SerializeField]
- private float offsetY = -50;
- [SerializeField]
- ImageFormat format = ImageFormat.PPM;
- private bool captureScreenShoot = false;
- private Rect previewRect, mainRect;
- private RenderTexture previewRenderTexture, mainRenderTexture;
- private Texture2D previewScreenShot, mainScreenShoot;
- [SerializeField]
- private Camera camera;
- private float minX, maxX, minY, maxY;
- private float width, height;
- public bool CaptureScreenShoot => captureScreenShoot;
- public float Scale { get => previewScale; set => previewScale = value; }
- public static Action<bool> TakeScreenshot;
- private void OnDestroy()
- {
- VectorElementController.FilledShape -= OnFilledShape;
- GeometryBuilder.LoadImageDone -= OnLoadImageDone;
- }
- private void Start()
- {
- GeometryBuilder.LoadImageDone += OnLoadImageDone;
- }
- /// <summary>
- /// <para> bounds = { minX, maxX, minY, maxY } </para>
- /// </summary>
- ///
- /// <param name="cameraPosition"></param>
- /// <param name="cameraOrthographicSize"></param>
- /// <param name="bounds"></param>
- public void Initialize(Vector3 cameraPosition, float[] bounds)
- {
- SetBounds(bounds);
- CalculateImageDimension();
- SetCamera(cameraPosition);
- DetermineRenderTexturePreviewImage(previewScale, ref previewRect,ref previewRenderTexture,ref previewScreenShot);
- DetermineRenderTextureNormalImage(mainScale,ref mainRect,ref mainRenderTexture, ref mainScreenShoot);
- }
- private void OnLoadImageDone()
- {
- CreateScreenShoot();
- geometryBuilder.ColorImage();
- CreateBMP();
- }
- private void OnFilledShape(int colorID)
- {
- // captureScreenShoot is needed because when color changed then invokes event we actually don't need.
- // Change color here is necessary to unselect elements which we haven't colored yet. We don't want to take a screenshoot with uncolored elements
- captureScreenShoot = true;
- // int currentColor = UIColorManager.CurrentColor;
- // uiColorManager.UnSelectColor();
- CreateScreenShoot();
- // uiColorManager.SelectColor(currentColor);
- captureScreenShoot = false;
- }
- //private void DetermineRenderTexture()
- //{
- // float offsetY = -50;
- // float topImageWorldPointY = camera.WorldToScreenPoint(new Vector3(0,maxY,0)).y;
- // int cameraRectWidth = (int)camera.pixelRect.width;
- // int cameraRectHeight = (int) camera.pixelRect.height;
- // float imageAndRectDiff = cameraRectHeight - topImageWorldPointY + offsetY;
- // rect = new Rect(0, imageAndRectDiff, cameraRectWidth, cameraRectHeight - Mathf.Abs(imageAndRectDiff));
- // renderTexture = new RenderTexture(cameraRectWidth, cameraRectHeight, 32);
- // screenShot = new Texture2D(cameraRectWidth , ((int)rect.height), TextureFormat.RGBA32, false);
- //}
- private void DetermineRenderTexturePreviewImage(float scaleFactor, ref Rect rect, ref RenderTexture renderTexture, ref Texture2D screenshoTexture2D)
- {
- int cameraRectWidth = (int)(scaleFactor * camera.pixelRect.width);
- int cameraRectHeight = (int)(scaleFactor * camera.pixelRect.height);
- // #if UNITY_EDITOR// - tak powinno byc kiedy tworzymy builda na windowsa
- #if !UNITY_EDITOR || !UNITY_STANDALONE// ! - test w edytorze
- float bottomImageWordPointY = scaleFactor * camera.WorldToScreenPoint(new Vector3(0, minY, 0)).y;
- float imageAndRectDiff = cameraRectHeight - Mathf.Abs(cameraRectHeight - bottomImageWordPointY ) + offsetY;
- rect = new Rect(0, imageAndRectDiff, cameraRectWidth, cameraRectHeight - imageAndRectDiff);
- renderTexture = new RenderTexture(cameraRectWidth, cameraRectHeight, 32);
- screenshoTexture2D = new Texture2D(cameraRectWidth, ((int)previewRect.height), TextureFormat.RGBA32, false);
- #else
- float topImageWorldPointY = scaleFactor * camera.WorldToScreenPoint(new Vector3(0, maxY, 0)).y;
- float imageAndRectDiff = cameraRectHeight - topImageWorldPointY + offsetY;
- rect = new Rect(0, imageAndRectDiff, cameraRectWidth, cameraRectHeight - Mathf.Abs(imageAndRectDiff));
- renderTexture = new RenderTexture(cameraRectWidth, cameraRectHeight, 32);
- screenshoTexture2D = new Texture2D(cameraRectWidth, ( (int) previewRect.height ), TextureFormat.RGBA32, false);
- #endif
- }
- private void DetermineRenderTextureNormalImage(float scaleFactor, ref Rect rect, ref RenderTexture renderTexture, ref Texture2D screenshoTexture2D)
- {
- int cameraRectWidth = (int)(scaleFactor * camera.pixelRect.width);
- int cameraRectHeight = (int)(scaleFactor * camera.pixelRect.height);
- // #if UNITY_EDITOR// - tak powinno byc kiedy tworzymy builda na windowsa
- #if !UNITY_EDITOR || !UNITY_STANDALONE// ! - test w edytorze
- float bottomImageWordPointY = scaleFactor * camera.WorldToScreenPoint(new Vector3(0, minY, 0)).y;
- float imageAndRectDiff = cameraRectHeight - Mathf.Abs(cameraRectHeight - bottomImageWordPointY ) + offsetY;
- rect = new Rect(0, imageAndRectDiff, cameraRectWidth, cameraRectHeight - imageAndRectDiff);
- renderTexture = new RenderTexture(cameraRectWidth, cameraRectHeight, 32);
- screenshoTexture2D = new Texture2D(cameraRectWidth, ((int)rect.height), TextureFormat.RGBA32, false);
- #else
- // float topImageWorldPointY = scaleFactor * camera.WorldToScreenPoint(new Vector3(0, maxY, 0)).y;
- float topImageWorldPointY = camera.WorldToScreenPoint(new Vector3(0, maxY, 0)).y * scaleFactor;
- // float topImageWorldPointY = camera.WorldToScreenPoint(new Vector3(0, maxY, 0)).y;
- float imageAndRectDiff = cameraRectHeight - topImageWorldPointY;// + offsetY;
- rect = new Rect(0, imageAndRectDiff, cameraRectWidth, cameraRectHeight - Mathf.Abs(imageAndRectDiff));
- renderTexture = new RenderTexture(cameraRectWidth, cameraRectHeight, 32);
- screenshoTexture2D = new Texture2D(cameraRectWidth, ((int)rect.height), TextureFormat.RGBA32, false);
- #endif
- }
- private void SetCamera(Vector3 cameraPosition)
- {
- AdjustCameraOrthographicSize();
- // On Android devices cutting a screenshot is starting from the bottom but in pc from the top
- #if UNITY_EDITOR || UNITY_STANDALONE_WIN || UNITY_STANDALONE // to jest ok, nie ruszac
- // transform.position = new Vector3(cameraPosition.x, -(Mathf.Abs(minY) - Mathf.Abs(minY/2)), 0);
- float bottomPoint = transform.InverseTransformPoint(camera.ViewportToWorldPoint(new Vector3(0, 0, 0))).y;
- // transform.position = new Vector3(cameraPosition.x, (Mathf.Abs(bottomPoint) - Mathf.Abs(minY)) - 2, 0);
- transform.position = new Vector3(cameraPosition.x, (Mathf.Abs(bottomPoint) - Mathf.Abs(minY)) , 0);
- #else
- //transform.position = new Vector3(cameraPosition.x, -(Mathf.Abs(maxY + maxY/2)),0);
- float topPoint = transform.InverseTransformPoint(camera.ViewportToWorldPoint(new Vector3(0, 1, 0))).y;
- transform.position = new Vector3(cameraPosition.x, - (topPoint-maxY) + 2, 0);
- #endif
- }
- private void AdjustCameraOrthographicSize()
- {
- // camera.orthographicSize = 80;
- var widthSize = width * Screen.height / Screen.width * 0.5f;// + offsetX;
- var heightSize = height / 2;// + offsetX;
- camera.orthographicSize = widthSize > heightSize ? widthSize : heightSize;
- //float screenRatio = (float)Screen.width / (float)Screen.height;
- //float targetRatio = width / height;
- //if (screenRatio >= targetRatio)
- //{
- // camera.orthographicSize = height / 2;
- //}
- //else
- //{
- // float differenceInSize = targetRatio / screenRatio;
- // camera.orthographicSize = height / 2 * differenceInSize;
- //}
- // camera.orthographicSize += 20;
- }
- private void SetBounds(float[] bounds)
- {
- minX = bounds[0];//* scale;
- maxX = bounds[1];//* scale;
- minY = bounds[2];//* scale;
- maxY = bounds[3]; //* scale;
- //minX = bounds[0]* mainScale;
- //maxX = bounds[1]* mainScale;
- //minY = bounds[2]* mainScale;
- //maxY = bounds[3]* mainScale;
- }
- private void CalculateImageDimension()
- {
- width = Mathf.Abs(maxX) + Mathf.Abs(minX);
- height = Mathf.Abs(maxY) + Mathf.Abs(minY);
- }
- public GameObject outlineContainer;
- [ContextMenu("Create Bitmap")]
- public void CreateBMP()
- {
- TakeScreenshot?.Invoke(false);
- outlineContainer.SetActive(false);
- camera.targetTexture = mainRenderTexture;
- camera.Render();
- // read pixels will read from the currently active render texture so make our offscreen
- // render texture active and then read the pixels
- RenderTexture.active = mainRenderTexture;
- mainScreenShoot.ReadPixels(mainRect, 0, 0);
- // reset active camera texture and render texture
- camera.targetTexture = null;
- RenderTexture.active = null;
- // DataStorageBase.CreateDirectory(DataStorageBase.MiniaturesDataPath);
- // string filename = Path.Combine(DataStorageBase.MiniaturesDataPath, DataStorageBase.ChosenImage);// + DataStorageBase.MiniaturesSavingExtension);
- // string filename = Path.Combine(DataStorageBase.MiniaturesDataPath, DataStorageBase.ChosenImage + ".png");
- string filename = DataStorageBase.ChosenImage.Replace(".svg", "Bitmap.svg");
- //DataStorageBase.ChosenImage;
- SaveTexture(filename, mainScreenShoot, format);
- outlineContainer.SetActive(true);
- TakeScreenshot?.Invoke(true);
- }
- [ContextMenu("Create SS")]
- public void CreateScreenShoot()
- {
- if (DataStorageBase.errorExists == true)
- {
- return;
- }
- TakeScreenshot?.Invoke(false);
- camera.targetTexture = previewRenderTexture;
- camera.Render();
- // read pixels will read from the currently active render texture so make our offscreen
- // render texture active and then read the pixels
- RenderTexture.active = previewRenderTexture;
- previewScreenShot.ReadPixels(previewRect, 0, 0);
- // reset active camera texture and render texture
- camera.targetTexture = null;
- RenderTexture.active = null;
- // DataStorageBase.CreateDirectory(DataStorageBase.MiniaturesDataPath);
- // string filename = Path.Combine(DataStorageBase.MiniaturesDataPath, DataStorageBase.ChosenImage);// + DataStorageBase.MiniaturesSavingExtension);
- // string filename = Path.Combine(DataStorageBase.MiniaturesDataPath, DataStorageBase.ChosenImage + ".png");
- string filename = DataStorageBase.ChosenImage;
- SaveTexture(filename,previewScreenShot, format);
- TakeScreenshot?.Invoke(true);
- }
- //public static void SaveTextureInMiniatureDirectory(string filename, Texture2D screenShot, ImageFormat format)
- //{
- // filename = Path.Combine(DataStorageBase.MiniaturesDataPath, filename + DataStorageBase.MiniaturesSavingExtension);
- // SaveTexture(filename, screenShot, format);
- //}
- private static void SaveTexture(string filename, Texture2D screenShot, ImageFormat format)
- {
- // pull in our file header/data bytes for the specified image format (has to be done from main thread)
- byte[] fileHeader = null;
- byte[] fileData = null;
- if (format == ImageFormat.RAW)
- {
- fileData = screenShot.GetRawTextureData();
- }
- else if (format == ImageFormat.PNG)
- {
- fileData = screenShot.EncodeToPNG();
- }
- else if (format == ImageFormat.JPG)
- {
- fileData = screenShot.EncodeToJPG();
- }
- else // ppm
- {
- // create a file header for ppm formatted file
- string headerStr = string.Format("P6\n{0} {1}\n255\n", screenShot.width, screenShot.height);
- fileHeader = System.Text.Encoding.ASCII.GetBytes(headerStr);
- fileData = screenShot.GetRawTextureData();
- }
- int x =filename.LastIndexOf("\\");
- string name = filename.Substring(x+1);
- filename = Path.Combine(DataStorageBase.MiniatureDirectory, name.Replace("svg", "png"));//DataStorageBase.MiniaturesSavingExtension);
- // create new thread to save the image to file (only operation that can be done in background)
- new System.Threading.Thread(() =>
- {
- // create file and write optional header with image bytes
- var f = System.IO.File.Create(filename);
- if (fileHeader != null)
- f.Write(fileHeader, 0, fileHeader.Length);
- f.Write(fileData, 0, fileData.Length);
- f.Close();
- }).Start();
- }
- }
- // configure with raw, jpg, png, or ppm (simple raw format)
- public enum ImageFormat
- {
- RAW,
- JPG,
- PNG,
- PPM
- };
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement