Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(promptimage): download as sprite - closes #114 #131

2 changes: 1 addition & 1 deletion package/Editor/ImageEditor/ImageEditorUI.cs
Original file line number Diff line number Diff line change
Expand Up @@ -793,7 +793,7 @@ private void SaveImage()
string saveImagePath = EditorUtility.SaveFilePanel("Save image", "", "", "png,jpeg,jpg");
if (!string.IsNullOrEmpty(saveImagePath))
{
CommonUtils.SaveTextureAsPNGAtPath(canvasImage, saveImagePath);
CommonUtils.SaveTextureAsPNG(canvasImage, saveImagePath);
}
}

Expand Down
77 changes: 52 additions & 25 deletions package/Editor/Plugins/CommonUtils.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,51 +22,54 @@ public static Texture2D CreateColorTexture(Color color)
return texture;
}

public static void SaveTextureAsPNGAtPath(Texture2D texture2D, string filePath)
/// <summary>
/// Take a byte array and save it as a file in the folder set in the Plugin Settings.
/// </summary>
/// <param name="pngBytes">The byte array to save as an image</param>
/// <param name="fileName">The file name you want. If null, it will take a random number</param>
/// <param name="importPreset">The preset you want to apply. if null, will use the default texture preset</param>
public static void SaveImageDataAsPNG(byte[] pngBytes, string fileName = "", Preset importPreset = null, Action<string> callback_OnSaved = null)
{
if (filePath == null || filePath == "") { Debug.LogError("Must have valid file path"); return; }
byte[] pngBytes = texture2D.EncodeToPNG();
SaveImageBytesToPath(filePath, pngBytes);
if (string.IsNullOrEmpty(fileName))
{
fileName = GetRandomImageFileName();
}

SaveImage(pngBytes, fileName, importPreset, callback_OnSaved);
}

public static void SaveImageBytesToPath(string filePath, byte[] pngBytes)
/// <summary>
/// Take a Texture2D and save it as a file in the folder set in the Plugin Settings.
/// </summary>
/// <param name="pngBytes">The byte array to save as an image</param>
/// <param name="fileName">The file name you want. If null, it will take a random number</param>
/// <param name="importPreset">The preset you want to apply. if null, will use the default texture preset</param>
public static void SaveTextureAsPNG(Texture2D texture2D, string fileName = "", Preset importPreset = null, Action<string> callback_OnSaved = null)
{
File.WriteAllBytes(filePath, pngBytes);
RefreshAssetDatabase();
Debug.Log("Saved image to: " + filePath);
SaveImageDataAsPNG(texture2D.EncodeToPNG(), fileName, importPreset, callback_OnSaved);
}

//possible improvement : Implement error handling and messages for cases where image loading or actions like "Download as Texture" fail. Inform the user of the issue and provide options for resolution or retries.
public static void SaveTextureAsPNG(Texture2D texture2D, string fileName = "", Preset importPreset = null)
private static void SaveImage(byte[] pngBytes, string fileName, Preset importPreset, Action<string> callback_OnSaved = null)
{
if (importPreset == null || string.IsNullOrEmpty(importPreset.name))
{
//Debug.LogWarning("Preset for this image is not set, using the one by default.");
importPreset = PluginSettings.TexturePreset;
}

if (fileName == null || fileName == "") { fileName = GetRandomImageFileName(); }

byte[] pngBytes = texture2D.EncodeToPNG();
SaveImageBytesToFile(fileName, pngBytes, (filePath) =>
{
ApplyImportSettingsFromPreset(filePath, importPreset);
});
}


public static void SaveImageBytesToFile(string fileName, byte[] pngBytes, Action<string> callback_OnAssetSaved = null)
{
string downloadPath = EditorPrefs.GetString("SaveFolder", "Assets");
string filePath = downloadPath + "/" + fileName;
string filePath = Path.Combine(downloadPath, fileName);

File.WriteAllBytesAsync(filePath, pngBytes).ContinueWith(task =>
{
try
{
RefreshAssetDatabase(() =>
{
Debug.Log("Downloaded image to: " + filePath);
callback_OnAssetSaved?.Invoke(filePath);
ApplyImportSettingsFromPreset(filePath, importPreset);
callback_OnSaved?.Invoke(filePath);
});
}
catch (Exception e)
Expand Down Expand Up @@ -163,6 +166,7 @@ public static string GetRandomSeedValue()

/// <summary>
/// Use this function to apply a specific Importer Preset to an image. (for example: apply the sprite settings if the user wants to make a sprite out of a generated image)
/// Found here : https://discussions.unity.com/t/editor-class-quot-texture-importer-quot-apply-import-settings-question/2538/4
/// </summary>
/// <param name="image">The image to apply the parameters</param>
/// <param name="preset">The preset that contains the parameter</param>
Expand All @@ -175,14 +179,37 @@ private static void ApplyImportSettingsFromPreset(string filePath, Preset import
//Debug.Log($"importPreset C {importPreset.name}");
//Debug.Log($"tImporter {tImporter}");

AssetDatabase.ImportAsset(filePath, ImportAssetOptions.ForceUpdate);
importPreset.ApplyTo(tImporter);
AssetDatabase.ImportAsset(filePath, ImportAssetOptions.ForceUpdate);
EditorGUIUtility.PingObject(AssetDatabase.LoadAssetAtPath<UnityEngine.Object>(filePath));
}
else
{
Debug.LogError("There was an issue when applying the preset. please restart the editor.");
}
}


/// <summary>
/// Use this function to modify the Pixels per Unit parameter of the texture
/// </summary>
/// <param name="filePath"></param>
public static void ApplyPixelsPerUnit(string filePath)
{
TextureImporter tImporter = AssetImporter.GetAtPath(filePath) as TextureImporter;
if (tImporter != null)
{
int width = 0;
int height = 0;
tImporter.GetSourceTextureWidthAndHeight(out width, out height);

tImporter.spritePixelsPerUnit = width;
AssetDatabase.ImportAsset(filePath, ImportAssetOptions.ForceUpdate);
}
else
{
Debug.LogError("There was an issue when applying the Pixels Per Unit parameter. please restart the editor.");
}
}
}
}
12 changes: 8 additions & 4 deletions package/Editor/PromptImages/PromptImages.cs
Original file line number Diff line number Diff line change
Expand Up @@ -144,12 +144,16 @@ private void OnDestroy()
DataCache.instance.ClearAllImageData();
}*/

internal void RemoveBackground(int selectedTextureIndex)
/// <summary>
/// Find the selected texture according to the current user selection and call the API to remove its background
/// </summary>
/// <param name="selectedTextureIndex"></param>
/// <param name="callback_OnBackgroundRemoved">Returns a callback with the byte array corresponding of the image (withouth background) data</param>
internal void RemoveBackground(int selectedTextureIndex, Action<byte[]> callback_OnBackgroundRemoved)
{
BackgroundRemoval.RemoveBackground(DataCache.instance.GetImageDataAtIndex(selectedTextureIndex).texture, bytes =>
BackgroundRemoval.RemoveBackground(DataCache.instance.GetImageDataAtIndex(selectedTextureIndex).texture, imageBytes =>
{
string fileName = CommonUtils.GetRandomImageFileName();
CommonUtils.SaveImageBytesToFile(fileName, bytes);
callback_OnBackgroundRemoved?.Invoke(imageBytes);
});
}
}
Expand Down
53 changes: 41 additions & 12 deletions package/Editor/PromptImages/PromptImagesUI.cs
Original file line number Diff line number Diff line change
Expand Up @@ -84,29 +84,58 @@ private void InitializeButtons()
}
},
{
"Delete", () =>
"Download as Sprite", () =>
{
// Delete the image at the selected index and clear the selected texture
promptImages.DeleteImageAtIndex(selectedTextureIndex);
buttonDetailPanelDrawFunction = () =>
string messageWhileDownloading = "Please wait... The background is currently being removed. The result will be downloaded in the folder you specified in the Scenario Plugin Settings.";
string messageSuccess = "Your image has been downloaded in the folder you specified in the Scenario Plugin Settings.";

//What to do when file is downloaded
Action<string> successAction = (filePath) =>
{
GUILayout.Label("Your image has been deleted.");
buttonDetailPanelDrawFunction = () =>
{
GUILayout.Label(messageSuccess, EditorStyles.wordWrappedLabel);
};

if (PluginSettings.UsePixelsUnitsEqualToImage)
{
CommonUtils.ApplyPixelsPerUnit(filePath);
}
};
selectedTexture = null;


if (PluginSettings.AlwaysRemoveBackgroundForSprites)
{
promptImages.RemoveBackground(selectedTextureIndex, (imageBytes) =>
{
CommonUtils.SaveImageDataAsPNG(imageBytes, null, PluginSettings.SpritePreset, successAction);
});

buttonDetailPanelDrawFunction = () =>
{
GUILayout.Label(messageWhileDownloading, EditorStyles.wordWrappedLabel);
};
}
else
{
CommonUtils.SaveTextureAsPNG(selectedTexture, null, PluginSettings.SpritePreset, successAction);
}
}
},
{ "Pixelate Image", () => PixelEditor.ShowWindow(selectedTexture, DataCache.instance.GetImageDataAtIndex(selectedTextureIndex))},
{ "Upscale Image", () => UpscaleEditor.ShowWindow(selectedTexture, DataCache.instance.GetImageDataAtIndex(selectedTextureIndex))},
{
"Remove Background", () =>
"Delete", () =>
{
promptImages.RemoveBackground(selectedTextureIndex);
// Delete the image at the selected index and clear the selected texture
promptImages.DeleteImageAtIndex(selectedTextureIndex);
buttonDetailPanelDrawFunction = () =>
{
GUILayout.Label("Your image has been dowloaded without background in the folder you specified in the Scenario Plugin Settings.", EditorStyles.wordWrappedLabel);
GUILayout.Label("Your image has been deleted.");
};
selectedTexture = null;
}
},
{ "Pixelate Image", () => PixelEditor.ShowWindow(selectedTexture, DataCache.instance.GetImageDataAtIndex(selectedTextureIndex))},
{ "Upscale Image", () => UpscaleEditor.ShowWindow(selectedTexture, DataCache.instance.GetImageDataAtIndex(selectedTextureIndex))}
}
};
}

Expand Down
52 changes: 41 additions & 11 deletions package/Editor/Settings/PluginSettings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,10 @@ public class PluginSettings : EditorWindow
#region Public Properties

public static string ApiUrl => "https://api.cloud.scenario.com/v1";
public static Preset TexturePreset { get { return GetTexturePreset(EditorPrefs.GetString("scenario/texturePreset")); } }

public static Preset TexturePreset { get { return GetPreset(EditorPrefs.GetString("scenario/texturePreset")); } }
public static Preset SpritePreset { get { return GetPreset(EditorPrefs.GetString("scenario/spritePreset")); } }
public static bool AlwaysRemoveBackgroundForSprites { get { return alwaysRemoveBackgroundForSprites; } }
public static bool UsePixelsUnitsEqualToImage { get { return usePixelUnitsEqualToImage; } }
#endregion

#region Private Properties
Expand All @@ -23,12 +25,14 @@ public class PluginSettings : EditorWindow
private string apiKey;
private string secretKey;
private string saveFolder;
private int imageFormatIndex;
private static float minimumWidth = 400f;
private static Preset texturePreset = null;

private static Preset texturePreset;
private string texturePresetGUID = null;
//private Preset spritePreset;

private Preset spritePreset;
private string spritePresetGUID = null;
private static bool alwaysRemoveBackgroundForSprites = true;
private static bool usePixelUnitsEqualToImage = true;

private static string vnumber => GetVersionFromPackageJson();
private static string version => $"Scenario Beta Version {vnumber}";
Expand Down Expand Up @@ -70,7 +74,9 @@ private void OnGUI()
GUILayout.Space(10);
DrawImageSettings();
GUILayout.Space(10);
DrawPresetSettings();
DrawTextureSettings();
GUILayout.Space(10);
DrawSpriteSettings();
GUILayout.Space(10);

if (GUILayout.Button("Save"))
Expand Down Expand Up @@ -119,14 +125,29 @@ private void DrawImageSettings()
EditorGUILayout.EndHorizontal();
}

private void DrawPresetSettings()
private void DrawTextureSettings()
{
GUILayout.Label("Preset Settings", EditorStyles.boldLabel);
GUILayout.Label("Texture Settings", EditorStyles.boldLabel);
texturePreset = (Preset)EditorGUILayout.ObjectField("Texture Preset", texturePreset, typeof(Preset), false);
texturePresetGUID = AssetDatabase.AssetPathToGUID(AssetDatabase.GetAssetPath(texturePreset));
}

private static Preset GetTexturePreset(string _GUID)
private void DrawSpriteSettings()
{
GUILayout.Label("Sprite Settings", EditorStyles.boldLabel);
spritePreset = (Preset)EditorGUILayout.ObjectField("Sprite Preset", spritePreset, typeof(Preset), false);
spritePresetGUID = AssetDatabase.AssetPathToGUID(AssetDatabase.GetAssetPath(spritePreset));

alwaysRemoveBackgroundForSprites = GUILayout.Toggle(alwaysRemoveBackgroundForSprites, new GUIContent("Always Remove Background For Sprites", "Will call the remove background API before downloading your images as sprite."));
usePixelUnitsEqualToImage = GUILayout.Toggle(usePixelUnitsEqualToImage, new GUIContent("Set Pixels Per Unit equal to image width", "If disable, the downloaded sprites will set the Pixels Per Unit settings equal to the value in the Preset. If enable, it will uses the width of the downloaded sprite as the value for Pixels per Unit."));
}

/// <summary>
/// Get a preset file from its GUID
/// </summary>
/// <param name="_GUID"></param>
/// <returns></returns>
private static Preset GetPreset(string _GUID)
{
if (_GUID != null)
{
Expand Down Expand Up @@ -190,6 +211,7 @@ public static string EncodedAuth
private void SaveSettings()
{
EditorPrefs.SetString("scenario/texturePreset", texturePresetGUID);
EditorPrefs.SetString("scenario/spritePreset", spritePresetGUID);
EditorPrefs.SetString("ApiKey", apiKey);
EditorPrefs.SetString("SecretKey", secretKey);
EditorPrefs.SetString("SaveFolder", saveFolder);
Expand All @@ -203,12 +225,20 @@ private void LoadSettings()
{
EditorPrefs.SetString("scenario/texturePreset", "28269680c775243409a2d470907383f9"); //change this value in case the meta file change
}
if (!EditorPrefs.HasKey("scenario/spritePreset"))
{
EditorPrefs.SetString("scenario/spritePreset", "d87ceacdb68f56745951dadf104120b1"); //change this value in case the meta file change
}

//load values
apiKey = EditorPrefs.GetString("ApiKey");
secretKey = EditorPrefs.GetString("SecretKey");
saveFolder = EditorPrefs.GetString("SaveFolder", "Assets");
texturePresetGUID = EditorPrefs.GetString("scenario/texturePreset");
texturePreset = AssetDatabase.LoadAssetAtPath<Preset>(AssetDatabase.GUIDToAssetPath(texturePresetGUID));
texturePreset = GetPreset(texturePresetGUID);
spritePresetGUID = EditorPrefs.GetString("scenario/spritePreset");
spritePreset = GetPreset(spritePresetGUID);
}

}
}
Loading