public void LoadFramesFromAsset(ImageSequence asset) { inputSequence.frames.Clear(); if (asset.inputFrameGUIDs != null && asset.inputFrameGUIDs.Count > 0) { int count = asset.inputFrameGUIDs.Count; int i = 1; foreach (string guid in asset.inputFrameGUIDs) { VFXToolboxGUIUtility.DisplayProgressBar("Image Sequencer", "Loading Textures (" + i + "/" + count + ")", (float)i / count, 0.1f); string path = AssetDatabase.GUIDToAssetPath(guid); Texture2D t = AssetDatabase.LoadAssetAtPath <Texture2D>(path); if (t != null) { inputSequence.frames.Add(new ProcessingFrame(t)); } else { inputSequence.frames.Add(ProcessingFrame.Missing); } i++; } VFXToolboxGUIUtility.ClearProgressBar(); } }
private bool HandleDropData() { if(m_CurrentAsset == null) return false; if(sidePanelViewMode == SidePanelMode.InputFrames && DragAndDrop.paths.Length > 0) { DragAndDrop.visualMode = DragAndDropVisualMode.Link; if( Event.current.type == EventType.DragExited) { List<string> texturePaths = new List<string>(); foreach(string path in DragAndDrop.paths) { if (VFXToolboxUtility.IsDirectory(path)) texturePaths.AddRange(VFXToolboxUtility.GetAllTexturesInPath(path)); else { VFXToolboxGUIUtility.DisplayProgressBar("Image Sequencer", "Discovering Assets...", 0.5f); Texture2D t = AssetDatabase.LoadAssetAtPath<Texture2D>(path); if(t != null) texturePaths.Add(path); } } AddInputFrame(m_InputFramesReorderableList, texturePaths); VFXToolboxGUIUtility.ClearProgressBar(); return true; } } return false; }
private void FindProperValues(float threshold, ref SerializedProperty top, ref SerializedProperty bottom, ref SerializedProperty left, ref SerializedProperty right) { int width = InputSequence.width; int height = InputSequence.height; int minX = width; int maxX = 0; int minY = height; int maxY = 0; Color[] colors; RenderTexture tempRT = RenderTexture.GetTemporary(width, height, 0, RenderTextureFormat.ARGBHalf, RenderTextureReadWrite.Linear); for (int i = 0; i < InputSequence.frames.Count; i++) { ProcessingFrame f = InputSequence.frames[i]; VFXToolboxGUIUtility.DisplayProgressBar("Crop processor", "Evaluating closest bound (Frame #" + i + " on " + InputSequence.frames.Count + "...)", (float)i / InputSequence.frames.Count); if (InputSequence.processor != null) { f.Process(); colors = VFXToolboxUtility.ReadBack(f.texture as RenderTexture); } else { Graphics.Blit(f.texture, tempRT); colors = VFXToolboxUtility.ReadBack(tempRT); } // Check frame for (int j = 0; j < colors.Length; j++) { int x = j % width; int y = j / width; if (colors[j].a >= threshold) { minX = Mathf.Min(minX, x); maxX = Mathf.Max(maxX, x); minY = Mathf.Min(minY, y); maxY = Mathf.Max(maxY, y); } } } VFXToolboxGUIUtility.ClearProgressBar(); bottom.intValue = minY; top.intValue = height - maxY - 1; left.intValue = minX; right.intValue = width - maxX - 1; RenderTexture.ReleaseTemporary(tempRT); }
public string ExportToFile(bool useCurrentFileName) { string path; if (useCurrentFileName) { path = m_CurrentAsset.exportSettings.fileName; } else { string title = "Save Texture, use # for frame numbering."; string defaultFileName, extension, message; switch (m_CurrentAsset.exportSettings.exportMode) { case ImageSequence.ExportMode.EXR: defaultFileName = "Frame_#.exr"; extension = "exr"; message = "Save as EXR Texture"; break; case ImageSequence.ExportMode.Targa: defaultFileName = "Frame_#.tga"; extension = "tga"; message = "Save as TGA Texture"; break; case ImageSequence.ExportMode.PNG: defaultFileName = "Frame_#.png"; extension = "png"; message = "Save as PNG Texture"; break; default: return(null); } path = EditorUtility.SaveFilePanelInProject(title, defaultFileName, extension, message); if (path == null || path == "") { return(""); } } int frameCount = m_processorStack.outputSequence.length; if (frameCount > 1 && !Path.GetFileNameWithoutExtension(path).Contains("#")) { if (!EditorUtility.DisplayDialog("VFX Toolbox", "You are currently exporting a sequence of images with no # in filename for numbering, do you want to add _# as a suffix of the filename?", "Add Postfix", "Cancel Export")) { return(""); } string newpath = Path.GetDirectoryName(path) + "\\" + Path.GetFileNameWithoutExtension(path) + "_#" + Path.GetExtension(path); path = newpath; } ImageSequence.ExportSettings settings = m_CurrentAsset.exportSettings; bool bCanceled = false; try { int i = 1; foreach (ProcessingFrame frame in m_processorStack.outputSequence.frames) { if (VFXToolboxGUIUtility.DisplayProgressBar("Image Sequencer", "Exporting Frame #" + i + "/" + frameCount, (float)i / frameCount, 0, true)) { bCanceled = true; break; } Color[] inputs; if (frame.texture is Texture2D) { RenderTexture temp = RenderTexture.GetTemporary(frame.texture.width, frame.texture.height, 0, RenderTextureFormat.ARGBHalf); Graphics.Blit((Texture2D)frame.texture, temp); inputs = ReadBack(temp); } else // frame.texture is RenderTexture { frame.Process(); inputs = ReadBack((RenderTexture)frame.texture); } string fileName = GetNumberedFileName(path, i, frameCount); switch (m_CurrentAsset.exportSettings.exportMode) { case ImageSequence.ExportMode.EXR: MiniEXR.MiniEXR.MiniEXRWrite(fileName, (ushort)frame.texture.width, (ushort)frame.texture.height, settings.exportAlpha, inputs, true); break; case ImageSequence.ExportMode.Targa: MiniTGA.MiniTGA.MiniTGAWrite(fileName, (ushort)frame.texture.width, (ushort)frame.texture.height, settings.exportAlpha, inputs); break; case ImageSequence.ExportMode.PNG: byte[] bytes; if (m_processorStack.outputSequence.processor != null) { RenderTexture backup = RenderTexture.active; Texture2D texture = new Texture2D(frame.texture.width, frame.texture.height, TextureFormat.RGBA32, settings.generateMipMaps, !settings.sRGB); RenderTexture.active = (RenderTexture)frame.texture; RenderTexture ldrOutput = RenderTexture.GetTemporary(frame.texture.width, frame.texture.height, 0, RenderTextureFormat.ARGB32, settings.sRGB? RenderTextureReadWrite.sRGB: RenderTextureReadWrite.Linear); GL.sRGBWrite = (QualitySettings.activeColorSpace == ColorSpace.Linear); Graphics.Blit(frame.texture, ldrOutput); RenderTexture.active = ldrOutput; texture.ReadPixels(new Rect(0, 0, frame.texture.width, frame.texture.height), 0, 0); bytes = texture.EncodeToPNG(); RenderTexture.active = backup; } else { bytes = (frame.texture as Texture2D).EncodeToPNG(); } File.WriteAllBytes(fileName, bytes); break; default: return(null); } AssetDatabase.Refresh(); TextureImporter importer = (TextureImporter)TextureImporter.GetAtPath(fileName); importer.wrapMode = m_CurrentAsset.exportSettings.wrapMode; importer.filterMode = m_CurrentAsset.exportSettings.filterMode; switch (m_CurrentAsset.exportSettings.dataContents) { case ImageSequence.DataContents.Color: importer.textureType = TextureImporterType.Default; break; case ImageSequence.DataContents.NormalMap: importer.textureType = TextureImporterType.NormalMap; importer.convertToNormalmap = false; break; case ImageSequence.DataContents.NormalMapFromGrayscale: importer.textureType = TextureImporterType.NormalMap; importer.convertToNormalmap = true; break; case ImageSequence.DataContents.Sprite: importer.textureType = TextureImporterType.Sprite; importer.spriteImportMode = SpriteImportMode.Multiple; importer.spritesheet = GetSpriteMetaData(frame, m_processorStack.outputSequence.numU, m_processorStack.outputSequence.numV); break; } importer.mipmapEnabled = m_CurrentAsset.exportSettings.generateMipMaps; switch (m_CurrentAsset.exportSettings.exportMode) { case ImageSequence.ExportMode.Targa: importer.sRGBTexture = m_CurrentAsset.exportSettings.sRGB; importer.alphaSource = m_CurrentAsset.exportSettings.exportAlpha ? TextureImporterAlphaSource.FromInput : TextureImporterAlphaSource.None; importer.textureCompression = m_CurrentAsset.exportSettings.compress ? TextureImporterCompression.Compressed : TextureImporterCompression.Uncompressed; break; case ImageSequence.ExportMode.EXR: importer.sRGBTexture = false; importer.alphaSource = (m_CurrentAsset.exportSettings.exportAlpha && !m_CurrentAsset.exportSettings.compress) ? TextureImporterAlphaSource.FromInput : TextureImporterAlphaSource.None; importer.textureCompression = m_CurrentAsset.exportSettings.compress ? TextureImporterCompression.CompressedHQ : TextureImporterCompression.Uncompressed; break; case ImageSequence.ExportMode.PNG: importer.sRGBTexture = m_CurrentAsset.exportSettings.sRGB; importer.alphaSource = m_CurrentAsset.exportSettings.exportAlpha ? TextureImporterAlphaSource.FromInput : TextureImporterAlphaSource.None; importer.textureCompression = m_CurrentAsset.exportSettings.compress ? TextureImporterCompression.Compressed : TextureImporterCompression.Uncompressed; break; } AssetDatabase.ImportAsset(fileName, ImportAssetOptions.ForceUpdate); // Separate Alpha if (m_CurrentAsset.exportSettings.exportSeparateAlpha) { string alphaFilename = fileName.Substring(0, fileName.Length - 4) + "_alpha.tga"; // build alpha for (int k = 0; k < inputs.Length; k++) { float a = inputs[k].a; inputs[k] = new Color(a, a, a, a); } MiniTGA.MiniTGA.MiniTGAWrite(alphaFilename, (ushort)frame.texture.width, (ushort)frame.texture.height, false, inputs); AssetDatabase.Refresh(); TextureImporter alphaImporter = (TextureImporter)TextureImporter.GetAtPath(alphaFilename); if (m_CurrentAsset.exportSettings.dataContents == ImageSequence.DataContents.Sprite) { alphaImporter.textureType = TextureImporterType.Sprite; alphaImporter.spriteImportMode = SpriteImportMode.Multiple; alphaImporter.spritesheet = GetSpriteMetaData(frame, m_processorStack.outputSequence.numU, m_processorStack.outputSequence.numV); alphaImporter.alphaSource = TextureImporterAlphaSource.None; } else { alphaImporter.textureType = TextureImporterType.SingleChannel; alphaImporter.alphaSource = TextureImporterAlphaSource.FromGrayScale; } alphaImporter.wrapMode = m_CurrentAsset.exportSettings.wrapMode; alphaImporter.filterMode = m_CurrentAsset.exportSettings.filterMode; alphaImporter.sRGBTexture = false; alphaImporter.mipmapEnabled = m_CurrentAsset.exportSettings.generateMipMaps; alphaImporter.textureCompression = m_CurrentAsset.exportSettings.compress ? TextureImporterCompression.Compressed : TextureImporterCompression.Uncompressed; AssetDatabase.ImportAsset(alphaFilename, ImportAssetOptions.ForceUpdate); } i++; } } catch (System.Exception e) { VFXToolboxGUIUtility.ClearProgressBar(); Debug.LogError(e.Message); } VFXToolboxGUIUtility.ClearProgressBar(); if (bCanceled) { return(""); } else { return(path); } }
public string ExportToFile(bool useCurrentFileName) { bool bIsInsideProject = true; string path; if (useCurrentFileName) { path = m_CurrentAsset.exportSettings.fileName; } else { string title = "Save Texture, use # for frame numbering."; string defaultFileName, extension; int count = m_ProcessingNodeStack.outputSequence.frames.Count; int numU = m_ProcessingNodeStack.outputSequence.numU; int numV = m_ProcessingNodeStack.outputSequence.numV; string defaultDir = Path.GetDirectoryName(AssetDatabase.GetAssetPath(m_CurrentAsset)); defaultFileName = m_CurrentAsset.name; if (count > 1) { defaultFileName += "_#"; } if (numU * numV != 1) { defaultFileName += "_" + numU + "x" + numV; } switch (m_CurrentAsset.exportSettings.exportMode) { case ImageSequence.ExportMode.EXR: defaultFileName += ".exr"; extension = "exr"; break; case ImageSequence.ExportMode.Targa: defaultFileName += ".tga"; extension = "tga"; break; case ImageSequence.ExportMode.PNG: defaultFileName += ".png"; extension = "png"; break; default: return(null); } path = EditorUtility.SaveFilePanel(title, defaultDir, defaultFileName, extension); if (path == null || path == "") { return(""); } if (path.Contains(Application.dataPath)) { path = path.Replace(Application.dataPath, "Assets"); } } if (!path.StartsWith("Assets/")) { bIsInsideProject = false; Debug.LogWarning("VFX Toolbox Warning : Saving a texture outside the project's scope. Import Settings will not be applied"); } int frameCount = m_ProcessingNodeStack.outputSequence.length; if (frameCount > 1 && !Path.GetFileNameWithoutExtension(path).Contains("#")) { if (!EditorUtility.DisplayDialog("VFX Toolbox", "You are currently exporting a sequence of images with no # in filename for numbering, do you want to add _# as a suffix of the filename?", "Add Postfix", "Cancel Export")) { return(""); } string newpath = Path.GetDirectoryName(path) + "\\" + Path.GetFileNameWithoutExtension(path) + "_#" + Path.GetExtension(path); path = newpath; } ImageSequence.ExportSettings settings = m_CurrentAsset.exportSettings; bool bCanceled = false; try { int i = 1; foreach (ProcessingFrame frame in m_ProcessingNodeStack.outputSequence.frames) { if (VFXToolboxGUIUtility.DisplayProgressBar("Image Sequencer", "Exporting Frame #" + i + "/" + frameCount, (float)i / frameCount, 0, true)) { bCanceled = true; break; } // Export frame : first, dump data into color array Color[] inputs; if (frame.texture is Texture2D) // if using input frame { RenderTexture temp = RenderTexture.GetTemporary(frame.texture.width, frame.texture.height, 0, RenderTextureFormat.ARGBHalf); Graphics.Blit((Texture2D)frame.texture, temp); inputs = ReadBack(temp); } else // frame.texture is RenderTexture { frame.Process(); inputs = ReadBack((RenderTexture)frame.texture); } string fileName = GetNumberedFileName(path, i, frameCount); // Dump data byte[] bytes; switch (m_CurrentAsset.exportSettings.exportMode) { case ImageSequence.ExportMode.EXR: #if UNITY_5_6_OR_NEWER // New Exporter { Texture2D texture = new Texture2D(frame.texture.width, frame.texture.height, TextureFormat.RGBAHalf, settings.generateMipMaps, !settings.sRGB); texture.SetPixels(inputs); texture.Apply(true); bytes = texture.EncodeToEXR(); } #else // Old Exporter { bytes = MiniEXR.MiniEXR.MiniEXRWrite((ushort)frame.texture.width, (ushort)frame.texture.height, settings.exportAlpha, inputs, true); } #endif break; case ImageSequence.ExportMode.Targa: { bytes = MiniTGA.MiniTGAWrite((ushort)frame.texture.width, (ushort)frame.texture.height, settings.exportAlpha, inputs); } break; case ImageSequence.ExportMode.PNG: { Texture2D texture = new Texture2D(frame.texture.width, frame.texture.height, TextureFormat.RGBA32, settings.generateMipMaps, !settings.sRGB); texture.SetPixels(inputs); texture.Apply(true); bytes = texture.EncodeToPNG(); } break; default: { bytes = new byte[0] { }; // Empty file that should not happen } break; } File.WriteAllBytes(fileName, bytes); AssetDatabase.Refresh(); // Process Import if saved inside project if (bIsInsideProject) { TextureImporter importer = (TextureImporter)TextureImporter.GetAtPath(fileName); importer.wrapMode = m_CurrentAsset.exportSettings.wrapMode; importer.filterMode = m_CurrentAsset.exportSettings.filterMode; switch (m_CurrentAsset.exportSettings.dataContents) { case ImageSequence.DataContents.Color: importer.textureType = TextureImporterType.Default; break; case ImageSequence.DataContents.NormalMap: importer.textureType = TextureImporterType.NormalMap; importer.convertToNormalmap = false; break; case ImageSequence.DataContents.NormalMapFromGrayscale: importer.textureType = TextureImporterType.NormalMap; importer.convertToNormalmap = true; break; case ImageSequence.DataContents.Sprite: importer.textureType = TextureImporterType.Sprite; importer.spriteImportMode = SpriteImportMode.Multiple; importer.spritesheet = GetSpriteMetaData(frame, m_ProcessingNodeStack.outputSequence.numU, m_ProcessingNodeStack.outputSequence.numV); break; } importer.mipmapEnabled = m_CurrentAsset.exportSettings.generateMipMaps; switch (m_CurrentAsset.exportSettings.exportMode) { case ImageSequence.ExportMode.Targa: importer.sRGBTexture = m_CurrentAsset.exportSettings.sRGB; importer.alphaSource = m_CurrentAsset.exportSettings.exportAlpha ? TextureImporterAlphaSource.FromInput : TextureImporterAlphaSource.None; importer.textureCompression = m_CurrentAsset.exportSettings.compress ? TextureImporterCompression.Compressed : TextureImporterCompression.Uncompressed; break; case ImageSequence.ExportMode.EXR: importer.sRGBTexture = false; importer.alphaSource = (m_CurrentAsset.exportSettings.exportAlpha && !m_CurrentAsset.exportSettings.compress) ? TextureImporterAlphaSource.FromInput : TextureImporterAlphaSource.None; importer.textureCompression = m_CurrentAsset.exportSettings.compress ? TextureImporterCompression.CompressedHQ : TextureImporterCompression.Uncompressed; break; case ImageSequence.ExportMode.PNG: importer.sRGBTexture = m_CurrentAsset.exportSettings.sRGB; importer.alphaSource = m_CurrentAsset.exportSettings.exportAlpha ? TextureImporterAlphaSource.FromInput : TextureImporterAlphaSource.None; importer.textureCompression = m_CurrentAsset.exportSettings.compress ? TextureImporterCompression.Compressed : TextureImporterCompression.Uncompressed; break; } AssetDatabase.ImportAsset(fileName, ImportAssetOptions.ForceUpdate); } // Separate Alpha if (m_CurrentAsset.exportSettings.exportSeparateAlpha) { string alphaFilename = fileName.Substring(0, fileName.Length - 4) + "_alpha.tga"; // build alpha for (int k = 0; k < inputs.Length; k++) { float a = inputs[k].a; inputs[k] = new Color(a, a, a, a); } MiniTGA.MiniTGAWrite(alphaFilename, (ushort)frame.texture.width, (ushort)frame.texture.height, false, inputs); AssetDatabase.Refresh(); // Process Importer for alpha if inside project if (bIsInsideProject) { TextureImporter alphaImporter = (TextureImporter)TextureImporter.GetAtPath(alphaFilename); if (m_CurrentAsset.exportSettings.dataContents == ImageSequence.DataContents.Sprite) { alphaImporter.textureType = TextureImporterType.Sprite; alphaImporter.spriteImportMode = SpriteImportMode.Multiple; alphaImporter.spritesheet = GetSpriteMetaData(frame, m_ProcessingNodeStack.outputSequence.numU, m_ProcessingNodeStack.outputSequence.numV); alphaImporter.alphaSource = TextureImporterAlphaSource.None; } else { alphaImporter.textureType = TextureImporterType.SingleChannel; alphaImporter.alphaSource = TextureImporterAlphaSource.FromGrayScale; } alphaImporter.wrapMode = m_CurrentAsset.exportSettings.wrapMode; alphaImporter.filterMode = m_CurrentAsset.exportSettings.filterMode; alphaImporter.sRGBTexture = false; alphaImporter.mipmapEnabled = m_CurrentAsset.exportSettings.generateMipMaps; alphaImporter.textureCompression = m_CurrentAsset.exportSettings.compress ? TextureImporterCompression.Compressed : TextureImporterCompression.Uncompressed; AssetDatabase.ImportAsset(alphaFilename, ImportAssetOptions.ForceUpdate); } } i++; } } catch (System.Exception e) { VFXToolboxGUIUtility.ClearProgressBar(); Debug.LogError(e.Message); } VFXToolboxGUIUtility.ClearProgressBar(); if (bCanceled) { return(""); } else { return(path); } }