Added Single Channel Node and Get Dimensions
As well as various bug fixes
This commit is contained in:
parent
deb2464537
commit
462bf4ffc0
@ -1,3 +1,4 @@
|
|||||||
|
using System.IO;
|
||||||
using Unity.Collections;
|
using Unity.Collections;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
@ -62,4 +63,25 @@ public struct ImageData
|
|||||||
texture.Apply();
|
texture.Apply();
|
||||||
return texture;
|
return texture;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void ExportPNG(string path)
|
||||||
|
{
|
||||||
|
Texture2D texture = this.ToTexture2D();
|
||||||
|
byte[] data = texture.EncodeToPNG();
|
||||||
|
string thePath;
|
||||||
|
|
||||||
|
if (path.StartsWith("Assets\\"))
|
||||||
|
{
|
||||||
|
thePath = path.Substring("Assets/".Length);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
thePath = path;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data != null)
|
||||||
|
{
|
||||||
|
System.IO.File.WriteAllBytes(Path.Combine(Application.dataPath, thePath), data);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -59,6 +59,8 @@ namespace ImageProcessingGraph.Editor
|
|||||||
|
|
||||||
// Log the elapsed time
|
// Log the elapsed time
|
||||||
UnityEngine.Debug.Log($"Graph execution took {stopwatch.ElapsedMilliseconds} milliseconds.");
|
UnityEngine.Debug.Log($"Graph execution took {stopwatch.ElapsedMilliseconds} milliseconds.");
|
||||||
|
|
||||||
|
AssetDatabase.Refresh();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -61,7 +61,7 @@ namespace ImageProcessingGraph.Editor
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (connection.Equals((default(GraphConnection))))
|
if (connection.Equals((default(GraphConnection))))
|
||||||
return;
|
continue;
|
||||||
|
|
||||||
// Get the output node from the connection
|
// Get the output node from the connection
|
||||||
var outputNode = asset.Nodes.FirstOrDefault(n => n.ID == connection.outputPort.nodeID);
|
var outputNode = asset.Nodes.FirstOrDefault(n => n.ID == connection.outputPort.nodeID);
|
23
Editor/Scripts/Editor/Nodes/Base/RangeProperty.cs
Normal file
23
Editor/Scripts/Editor/Nodes/Base/RangeProperty.cs
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
using System;
|
||||||
|
using UnityEngine.UIElements;
|
||||||
|
|
||||||
|
namespace ImageProcessingGraph.Editor
|
||||||
|
{
|
||||||
|
[Serializable]
|
||||||
|
public class GreyscaleValue
|
||||||
|
{
|
||||||
|
public int value = 255;
|
||||||
|
|
||||||
|
public GreyscaleValue()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class GreyscaleField : IntegerField
|
||||||
|
{
|
||||||
|
public (int, int) minMax = (0,255);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
3
Editor/Scripts/Editor/Nodes/Base/RangeProperty.cs.meta
Normal file
3
Editor/Scripts/Editor/Nodes/Base/RangeProperty.cs.meta
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 3ab37c25c4884480b8777a62e042a37c
|
||||||
|
timeCreated: 1745703416
|
@ -1,3 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: ca37b9337d41484892c89933479f1e7f
|
|
||||||
timeCreated: 1743745541
|
|
@ -1,3 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: 1646a2bcaf6b4de488cadad1d7cdf795
|
|
||||||
timeCreated: 1743747481
|
|
@ -1,20 +0,0 @@
|
|||||||
using ImageProcessingGraph.Editor.Nodes.NodeAttributes;
|
|
||||||
using Unity.Collections;
|
|
||||||
using UnityEditor;
|
|
||||||
using UnityEngine;
|
|
||||||
|
|
||||||
namespace ImageProcessingGraph.Editor.Nodes.Output
|
|
||||||
{
|
|
||||||
[NodeInfo("Texture Export", "Export/Texture2D", true)]
|
|
||||||
public class Texture2DOutput : BaseImageNode
|
|
||||||
{
|
|
||||||
[NodeAttributes.Input("")] public ImageData inputPixels;
|
|
||||||
[NodeAttributes.Input("File Name")] public string fileName;
|
|
||||||
[NodeAttributes.Input("File Path")] public string fileDirectory;
|
|
||||||
|
|
||||||
public override void Process()
|
|
||||||
{
|
|
||||||
AssetDatabase.CreateAsset(inputPixels.ToTexture2D(), $"{fileDirectory}/{fileName}.asset");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,5 +1,5 @@
|
|||||||
fileFormatVersion: 2
|
fileFormatVersion: 2
|
||||||
guid: 22b0f0e553dc85e489979a232505a332
|
guid: cf47dea8bd47175418a3f462e2ddb060
|
||||||
folderAsset: yes
|
folderAsset: yes
|
||||||
DefaultImporter:
|
DefaultImporter:
|
||||||
externalObjects: {}
|
externalObjects: {}
|
8
Editor/Scripts/Editor/Nodes/Types/Image.meta
Normal file
8
Editor/Scripts/Editor/Nodes/Types/Image.meta
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 3d053e80c499447499397a64b22ee639
|
||||||
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
8
Editor/Scripts/Editor/Nodes/Types/Image/Adjustments.meta
Normal file
8
Editor/Scripts/Editor/Nodes/Types/Image/Adjustments.meta
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: e6bd53786a8dee54790032792e0b03da
|
||||||
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
8
Editor/Scripts/Editor/Nodes/Types/Image/Channels.meta
Normal file
8
Editor/Scripts/Editor/Nodes/Types/Image/Channels.meta
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 6957ba197a1612a4c8f0f588d40e374f
|
||||||
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
@ -1,4 +1,5 @@
|
|||||||
using ImageProcessingGraph.Editor.Nodes.NodeAttributes;
|
using ImageProcessingGraph.Editor.Nodes.NodeAttributes;
|
||||||
|
using Unity.Burst;
|
||||||
using Unity.Collections;
|
using Unity.Collections;
|
||||||
using Unity.Jobs;
|
using Unity.Jobs;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
@ -53,6 +54,7 @@ namespace ImageProcessingGraph.Editor.Nodes.Fun_Nodes.Texture
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Job struct for processing the image data
|
// Job struct for processing the image data
|
||||||
|
[BurstCompile]
|
||||||
struct RGBAJob : IJob
|
struct RGBAJob : IJob
|
||||||
{
|
{
|
||||||
public NativeArray<Color32> pixelData;
|
public NativeArray<Color32> pixelData;
|
8
Editor/Scripts/Editor/Nodes/Types/Image/Dimensions.meta
Normal file
8
Editor/Scripts/Editor/Nodes/Types/Image/Dimensions.meta
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: d31e8b213de87c54caaf096620201846
|
||||||
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
@ -0,0 +1,27 @@
|
|||||||
|
using ImageProcessingGraph.Editor.Nodes.NodeAttributes;
|
||||||
|
using Unity.Burst;
|
||||||
|
using Unity.Collections;
|
||||||
|
using Unity.Jobs;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace ImageProcessingGraph.Editor.Nodes.Fun_Nodes.Texture
|
||||||
|
{
|
||||||
|
[NodeInfoAttribute("Get Dimensions", "Dimensions/Get Dimensions", false)]
|
||||||
|
public class TextureGetDimensions : BaseImageNode
|
||||||
|
{
|
||||||
|
[NodeAttributes.Input("")]
|
||||||
|
public ImageData inputTexture;
|
||||||
|
|
||||||
|
[NodeAttributes.Output("Width")]
|
||||||
|
public int width;
|
||||||
|
|
||||||
|
[NodeAttributes.Output("Height")]
|
||||||
|
public int height;
|
||||||
|
|
||||||
|
public override void Process()
|
||||||
|
{
|
||||||
|
this.width = inputTexture.Width;
|
||||||
|
this.height = inputTexture.Height;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,3 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 71e1db2a5bfe4a54a6ce2a99fe4d02fb
|
||||||
|
timeCreated: 1745699625
|
@ -0,0 +1,37 @@
|
|||||||
|
using System.ComponentModel.Composition.Primitives;
|
||||||
|
using ImageProcessingGraph.Editor.Nodes.NodeAttributes;
|
||||||
|
using Unity.Collections;
|
||||||
|
using UnityEditor;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace ImageProcessingGraph.Editor.Nodes.Output
|
||||||
|
{
|
||||||
|
[NodeInfo("Texture Export", "Export/Texture2D", true)]
|
||||||
|
public class Texture2DOutput : BaseImageNode
|
||||||
|
{
|
||||||
|
[NodeAttributes.Input("")] public ImageData inputPixels;
|
||||||
|
[NodeAttributes.Input("File Name")] public string fileName;
|
||||||
|
[NodeAttributes.Input("File Path")] public string fileDirectory;
|
||||||
|
|
||||||
|
public enum ExportType
|
||||||
|
{
|
||||||
|
Texture2D,
|
||||||
|
PNG
|
||||||
|
}
|
||||||
|
|
||||||
|
[NodeAttributes.Input("Export Type")] public ExportType exportType;
|
||||||
|
|
||||||
|
public override void Process()
|
||||||
|
{
|
||||||
|
switch (exportType)
|
||||||
|
{
|
||||||
|
case ExportType.Texture2D:
|
||||||
|
AssetDatabase.CreateAsset(inputPixels.ToTexture2D(), $"{fileDirectory}/{fileName}.asset");
|
||||||
|
break;
|
||||||
|
case ExportType.PNG:
|
||||||
|
inputPixels.ExportPNG($"{fileDirectory}/{fileName}.png");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
8
Editor/Scripts/Editor/Nodes/Types/Image/Filters.meta
Normal file
8
Editor/Scripts/Editor/Nodes/Types/Image/Filters.meta
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 96b583a3bbd8b2c45a5eaa9e0f00d1b2
|
||||||
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
8
Editor/Scripts/Editor/Nodes/Types/Image/Image.meta
Normal file
8
Editor/Scripts/Editor/Nodes/Types/Image/Image.meta
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: bf8e2895a77954d45864e9f8edae29c3
|
||||||
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
@ -6,7 +6,7 @@ using UnityEngine;
|
|||||||
|
|
||||||
namespace ImageProcessingGraph.Editor.Nodes.Import_Nodes
|
namespace ImageProcessingGraph.Editor.Nodes.Import_Nodes
|
||||||
{
|
{
|
||||||
[NodeInfo("Texture Import", "Imports/Texture2D", true)]
|
[NodeInfo("Texture Import", "Imports/Import Texture", true)]
|
||||||
public class Texture2DImport : BaseImageNode
|
public class Texture2DImport : BaseImageNode
|
||||||
{
|
{
|
||||||
[NodeAttributes.Input("")]
|
[NodeAttributes.Input("")]
|
||||||
@ -23,6 +23,20 @@ namespace ImageProcessingGraph.Editor.Nodes.Import_Nodes
|
|||||||
{
|
{
|
||||||
if (this.textureImport != null)
|
if (this.textureImport != null)
|
||||||
{
|
{
|
||||||
|
TextureImporter textureImporter = AssetImporter.GetAtPath(AssetDatabase.GetAssetPath(textureImport)) as TextureImporter;
|
||||||
|
|
||||||
|
TextureImporterPlatformSettings texset = textureImporter.GetDefaultPlatformTextureSettings();
|
||||||
|
texset.format=TextureImporterFormat.RGBA32;
|
||||||
|
texset.maxTextureSize=16384;
|
||||||
|
textureImporter.SetPlatformTextureSettings(texset);
|
||||||
|
|
||||||
|
TextureImporterSettings settings = new TextureImporterSettings();
|
||||||
|
textureImporter.ReadTextureSettings(settings);
|
||||||
|
settings.readable = true;
|
||||||
|
textureImporter.SetTextureSettings(settings);
|
||||||
|
textureImporter.SaveAndReimport();
|
||||||
|
|
||||||
|
|
||||||
this.textureOutput = new ImageData(textureImport);
|
this.textureOutput = new ImageData(textureImport);
|
||||||
this.fileName = textureImport.name;
|
this.fileName = textureImport.name;
|
||||||
this.filePath = Path.GetDirectoryName(AssetDatabase.GetAssetPath(textureImport));
|
this.filePath = Path.GetDirectoryName(AssetDatabase.GetAssetPath(textureImport));
|
8
Editor/Scripts/Editor/Nodes/Types/Image/Utilities.meta
Normal file
8
Editor/Scripts/Editor/Nodes/Types/Image/Utilities.meta
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: c524131b4dbc3414ab755a10441b3841
|
||||||
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
@ -0,0 +1,63 @@
|
|||||||
|
using ImageProcessingGraph.Editor.Nodes.NodeAttributes;
|
||||||
|
using Unity.Burst;
|
||||||
|
using Unity.Collections;
|
||||||
|
using Unity.Jobs;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace ImageProcessingGraph.Editor.Nodes.Types.Image.Utilities
|
||||||
|
{
|
||||||
|
public class SingleChannelColor
|
||||||
|
{
|
||||||
|
[NodeInfoAttribute("Channel Color", "Utility/Channel Color", false)]
|
||||||
|
public class SingleColorChannel : BaseImageNode
|
||||||
|
{
|
||||||
|
[NodeAttributes.Input("Color")] public GreyscaleValue range;
|
||||||
|
|
||||||
|
[NodeAttributes.Input("Width")] public int Width;
|
||||||
|
|
||||||
|
[NodeAttributes.Input("Height")] public int Height;
|
||||||
|
|
||||||
|
[NodeAttributes.Output("Color")] public SplitChannelData OutputColor;
|
||||||
|
|
||||||
|
public override void Process()
|
||||||
|
{
|
||||||
|
int pixelCount = Width * Height;
|
||||||
|
|
||||||
|
NativeArray<byte> outputData = new NativeArray<byte>(pixelCount * 4, Allocator.TempJob);
|
||||||
|
|
||||||
|
CreateSingleColorJob job = new CreateSingleColorJob
|
||||||
|
{
|
||||||
|
color32 = range.value,
|
||||||
|
outputData = outputData,
|
||||||
|
width = Width,
|
||||||
|
height = Height
|
||||||
|
};
|
||||||
|
|
||||||
|
job.Run();
|
||||||
|
|
||||||
|
OutputColor = new SplitChannelData(outputData.ToArray(), (Width, Height));
|
||||||
|
|
||||||
|
outputData.Dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
[BurstCompile]
|
||||||
|
struct CreateSingleColorJob : IJob
|
||||||
|
{
|
||||||
|
public int color32;
|
||||||
|
[WriteOnly]
|
||||||
|
public NativeArray<byte> outputData;
|
||||||
|
public int width;
|
||||||
|
public int height;
|
||||||
|
|
||||||
|
public void Execute()
|
||||||
|
{
|
||||||
|
// More efficient linear write pattern
|
||||||
|
for (int i = 0; i < width*height*4; i++)
|
||||||
|
{
|
||||||
|
outputData[i] = (byte)color32;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,3 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: aef9d7bde3d544e6bca5eef8ff58a60e
|
||||||
|
timeCreated: 1745699866
|
8
Editor/Scripts/Editor/Nodes/Types/String.meta
Normal file
8
Editor/Scripts/Editor/Nodes/Types/String.meta
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 77d8c5639ebc40947940b6b150aad306
|
||||||
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
@ -120,8 +120,9 @@ namespace ImageProcessingGraph.Editor.Unity_Image_Processing.Scripts.Editor.Wind
|
|||||||
if (propertyField != null)
|
if (propertyField != null)
|
||||||
{
|
{
|
||||||
// Register a callback for when the value changes
|
// Register a callback for when the value changes
|
||||||
if (propertyField is IntegerField intField)
|
if (propertyField.GetType() == typeof(IntegerField))
|
||||||
{
|
{
|
||||||
|
var intField = propertyField as IntegerField;
|
||||||
intField.RegisterValueChangedCallback(evt =>
|
intField.RegisterValueChangedCallback(evt =>
|
||||||
{
|
{
|
||||||
field.SetValue(graphNode, evt.newValue); // Update the field with the new value
|
field.SetValue(graphNode, evt.newValue); // Update the field with the new value
|
||||||
@ -176,6 +177,29 @@ namespace ImageProcessingGraph.Editor.Unity_Image_Processing.Scripts.Editor.Wind
|
|||||||
field.SetValue(graphNode, evt.newValue); // Update the field with the new value
|
field.SetValue(graphNode, evt.newValue); // Update the field with the new value
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
else if (propertyField is EnumField enumField)
|
||||||
|
{
|
||||||
|
enumField.RegisterValueChangedCallback(evt =>
|
||||||
|
{
|
||||||
|
field.SetValue(graphNode, evt.newValue); // 🎯 Update the field with the new enum value
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else if (propertyField.GetType() == typeof(GreyscaleField))
|
||||||
|
{
|
||||||
|
var greyscaleField = propertyField as GreyscaleField;
|
||||||
|
greyscaleField.RegisterValueChangedCallback(evt =>
|
||||||
|
{
|
||||||
|
var value = (GreyscaleValue)field.GetValue(graphNode);
|
||||||
|
|
||||||
|
if(evt.newValue > greyscaleField.minMax.Item2)
|
||||||
|
value.value = greyscaleField.minMax.Item2;
|
||||||
|
else if(evt.newValue < greyscaleField.minMax.Item1)
|
||||||
|
value.value = greyscaleField.minMax.Item1;
|
||||||
|
|
||||||
|
value.value = (int)evt.newValue;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
propertyFieldContainer.Add(propertyField);
|
propertyFieldContainer.Add(propertyField);
|
||||||
port.Add(propertyFieldContainer);
|
port.Add(propertyFieldContainer);
|
||||||
@ -192,7 +216,6 @@ namespace ImageProcessingGraph.Editor.Unity_Image_Processing.Scripts.Editor.Wind
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create appropriate property field based on the type of the variable
|
|
||||||
private VisualElement CreatePropertyFieldForType(Type type, object value)
|
private VisualElement CreatePropertyFieldForType(Type type, object value)
|
||||||
{
|
{
|
||||||
if (type == typeof(int))
|
if (type == typeof(int))
|
||||||
@ -235,11 +258,24 @@ namespace ImageProcessingGraph.Editor.Unity_Image_Processing.Scripts.Editor.Wind
|
|||||||
var objectField = new ObjectField { value = (Texture2D)value, objectType = typeof(Texture2D) };
|
var objectField = new ObjectField { value = (Texture2D)value, objectType = typeof(Texture2D) };
|
||||||
return objectField;
|
return objectField;
|
||||||
}
|
}
|
||||||
|
else if (type.IsEnum) // 💥✨ ENUMS, BABY! 💥✨
|
||||||
|
{
|
||||||
|
var enumField = new EnumField((Enum)value);
|
||||||
|
return enumField;
|
||||||
|
}
|
||||||
|
else if (type == typeof(GreyscaleValue))
|
||||||
|
{
|
||||||
|
|
||||||
// Add more types as needed (Vector3, etc.)
|
var greyscaleValue = (GreyscaleValue)value;
|
||||||
|
var intField = new GreyscaleField { value = (int)greyscaleValue.value };
|
||||||
|
return intField;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add more types as needed
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void SavePosition() => graphNode.SetPosition(GetPosition());
|
public void SavePosition() => graphNode.SetPosition(GetPosition());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user