using System; using System.Collections; using System.Collections.Generic; using System.Drawing; using System.IO; using Emgu.CV; using ImageMagick; using UnityEngine; using UnityEngine.UI; public class CharRenderer : MonoBehaviour { [HideInInspector] public List renderedTextures = new List(); public int framesPerSecond = 30; public GameObject loadingBarParent; public Slider progressBar; public Text whatIsLoading; private string loadingTextBase = "Currently Loading: \n"; private Size currentSize; public bool greenScreen; private List textureMats; private void Start() { loadingBarParent.SetActive(false); } public void SelectFileToSaveRender() { Stream stream; System.Windows.Forms.SaveFileDialog sfd = new System.Windows.Forms.SaveFileDialog(); string title = "Select where to put your rendered gif"; sfd.Title = title; sfd.Filter = "Mp4 (*.mp4) | *.mp4"; sfd.FilterIndex = 1; if (sfd.ShowDialog() == System.Windows.Forms.DialogResult.OK) { stream = sfd.OpenFile(); if (stream != null) { FileStream file = stream as FileStream; if (file != null) { RenderByFiles(file.Name); } stream.Close(); } } } public void RenderByFiles(string path) { renderedTextures.Clear(); loadingBarParent.SetActive(true); whatIsLoading.text = loadingTextBase + "Starting"; progressBar.minValue = 0; progressBar.value = 0; int maxValue = 0; maxValue = InfoSingleton.Instance.talker.source.clip.samples / (InfoSingleton.Instance.talker.source.clip.frequency / framesPerSecond); maxValue += 2; progressBar.maxValue = maxValue; textureMats = new List(); StartCoroutine(RenderCouritine(path)); } IEnumerator RenderCouritine(string path) { List imagePathList = new List(); currentSize = new Size(InfoSingleton.Instance.talker.ReturnCharImageOnPPos(0).width, InfoSingleton.Instance.talker.ReturnCharImageOnPPos(0).height); int num = 0; string temporalFilesPath = path.Substring(0,path.LastIndexOf("\\")); print("temporalFiles " + temporalFilesPath); print("Starting render"); for (int i = 0; i < InfoSingleton.Instance.talker.source.clip.samples; i = i + InfoSingleton.Instance.talker.source.clip.frequency/framesPerSecond) { print("Rendering image number " + num); whatIsLoading.text = loadingTextBase + "Rendering image number " + num; Texture2D starter = InfoSingleton.Instance.talker.ReturnCharImageOnPPos(i); Texture2D beingSaved = greenScreen ? FromTransparentToColor(starter, new UnityEngine.Color(0, 1, 0, 1)) : starter; renderedTextures.Add(beingSaved); byte[] tempImageData = beingSaved.EncodeToPNG(); Mat nMat = new Mat(); CvInvoke.Imdecode(tempImageData,Emgu.CV.CvEnum.ImreadModes.Unchanged,nMat); //Mat resizedMat = new Mat(nMat.Size*2,nMat.Depth,nMat.NumberOfChannels); //CvInvoke.WarpAffine(nMat, resizedMat,resizedMat.Size,0,0); textureMats.Add(nMat); string numberStringed = num.ToString("000"); System.IO.File.WriteAllBytes(temporalFilesPath + "\\imagenNumero-" + numberStringed + ".png", tempImageData); imagePathList.Add(temporalFilesPath + "\\imagenNumero-" + numberStringed + ".png"); num++; progressBar.value += 1; yield return new WaitForSeconds(0.01f); } if(imagePathList.Count > 0) { progressBar.value += 1; //TurnImagesToGif(path,imagePathList); TurnImagesToMP4(path,imagePathList); } else { //TODO ERROR POPUP loadingBarParent.SetActive(false); } } private void TurnImagesToGif(string savePath,List imagePathList) { whatIsLoading.text = loadingTextBase + "Now turning images into gif"; MagickImageCollection imageCollection = new MagickImageCollection(); //int z = 0; foreach (string imagePath in imagePathList) { MagickImage imageToAdd = new MagickImage(imagePath); uint delay = 0; delay = (uint) Mathf.RoundToInt(100f / (float)framesPerSecond); print("El delay es " + delay); imageToAdd.AnimationDelay = delay; imageToAdd.GifDisposeMethod = GifDisposeMethod.Previous; imageCollection.Add(imageToAdd); } imageCollection.OptimizeTransparency(); //imageCollection.Optimize(); print("Turning to video"); string fixedPath = savePath; if (!savePath.ToLower().EndsWith(".gif")) { fixedPath += ".gif"; } imageCollection.WriteAsync(fixedPath); foreach (string path in imagePathList) { System.IO.File.Delete(path); } whatIsLoading.text = loadingTextBase + "Images turned into gif"; progressBar.value += 1; print("Done, video in " + savePath); } private void TurnImagesToMP4(string savePath, List imagePathList) { whatIsLoading.text = loadingTextBase + "Now turning images into video"; Backend[] backE = CvInvoke.Backends; VideoWriter writer; //int codec1 = VideoWriter.Fourcc('a', 'p', 'c', 'n'); int codec1 = VideoWriter.Fourcc('H', '2', '6', '4'); int backend_idx = 0; foreach (Backend item in backE) { if (item.Name.Equals("MSMF")) { backend_idx = item.ID; break; } } if(currentSize == null) { currentSize = new Size(1920, 1080); } writer = new VideoWriter(savePath,backend_idx,codec1, framesPerSecond, currentSize,true); //writer = new VideoWriter(String.Format("video_out.mp4"),backend_idx,codec1, framesPerSecond, currentSize,true); //List imageMats = new List(); //foreach (string path in imagePathList) //{ // imageMats.Add(CvInvoke.Imread(path)); //} foreach(Mat mat in textureMats) { writer.Write(mat); } foreach (string path in imagePathList) { System.IO.File.Delete(path); } writer.Dispose(); progressBar.value += 1; whatIsLoading.text = loadingTextBase + "Images turned into video"; loadingBarParent.SetActive(false); } private Texture2D FromTransparentToColor(Texture2D starter, UnityEngine.Color selectedColor) { Texture2D toReturn = starter; for (int x = 0; x < currentSize.Width; x++) { for (int y = 0; y < currentSize.Height; y++) { UnityEngine.Color pixelColor = toReturn.GetPixel(x, y); if (pixelColor.a <= 0f) { toReturn.SetPixel(x, y, selectedColor); } else if(pixelColor.a > 0 && pixelColor.a <= 1f) { toReturn.SetPixel(x, y, new UnityEngine.Color(pixelColor.r,pixelColor.g,pixelColor.b,1)); } } } return toReturn; } //Get audio //string audioPath = "F:\\PruebaAutoHablador\\1\\extractedAudio.wav"; //print("Extracting audio"); //float[] samples = new float[InfoSingleton.Instance.talker.source.clip.samples]; //InfoSingleton.Instance.talker.source.clip.GetData(samples, 0); //byte[] audioData = BitConverter.DoubleToInt64Bits(samples); //print("Adding audio"); //FFMpeg.ReplaceAudio("F:\\PruebaAutoHablador\\1\\joinedVideo.mp4",audioPath, "F:\\PruebaAutoHablador\\1\\joinedVideo.mp4"); //MemoryStream imgStream = new MemoryStream(tempImageData); //Bitmap imageMap = new Bitmap(imgStream); //System.Drawing.Image img = System.Drawing.Image.FromStream(imgStream); //System.Drawing.Graphics g = System.Drawing.Graphics.FromImage(imageMap); ////TODO add color selection //g.Clear(System.Drawing.Color.FromArgb(255,0,255,0)); //g.DrawImageUnscaled(img,0,0); //byte[] finalImage = (byte[])new ImageConverter().ConvertTo(imageMap, typeof(byte[])); }