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(imageswindow): merge the prompt image window and the images window - closes #135 #137

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions package/Editor/Images/ImageDataClasses.cs
Original file line number Diff line number Diff line change
@@ -1,27 +1,27 @@
using System;
using System.Collections.Generic;
using System.Numerics;
using UnityEngine;

namespace Scenario.Editor
{
public static class ImageDataStorage
{
[System.Serializable]
[Serializable]
public class ImageData
{
[SerializeField] public string Id;
[SerializeField] public string Url;
[SerializeField] public string InferenceId;
[SerializeField] public string Prompt;
[SerializeField] public float Steps;
[SerializeField] public UnityEngine.Vector2 Size;
[SerializeField] public int Steps;
[SerializeField] public Vector2 Size;
[SerializeField] public float Guidance;
[SerializeField] public string Scheduler;
[SerializeField] public string Seed;
[SerializeField] public DateTime CreatedAt;
[SerializeField] public Texture2D texture;
[SerializeField] public bool isProcessedByPromptImages;
[SerializeField] public string modelId;
}
}

Expand Down Expand Up @@ -70,7 +70,7 @@ public class Inference
public string status { get; set; }
public List<Image> images { get; set; }
public int imagesNumber { get; set; }
public int progress { get; set; }
public float progress { get; set; }
public string displayPrompt { get; set; }
}

Expand Down
156 changes: 80 additions & 76 deletions package/Editor/Images/Images.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Newtonsoft.Json;
using UnityEditor;
using UnityEngine;
Expand All @@ -8,26 +9,29 @@ namespace Scenario.Editor
{
public class Images : EditorWindow
{
private static readonly string PaginationTokenKey = "paginationToken";
private static readonly float MinimumWidth = 1000f;
private static readonly float MinimumHeight = 700f;
private static readonly ImagesUI ImagesUI = new();

private static string _paginationToken = "";
internal static List<ImageDataStorage.ImageData> _imageDataList = new();
internal static List<ImageDataStorage.ImageData> imageDataList = new();

/// <summary>
/// Contains a token that is useful to get the next page of inferences
/// </summary>
private static string lastPageToken = string.Empty;

private static bool isVisible = false;

[MenuItem("Window/Scenario/Images")]
public static void ShowWindow()
{
Images window = GetWindow<Images>("Images");

if (isVisible)
return;

lastPageToken = string.Empty;
imageDataList.Clear();
GetInferencesData();

var images = EditorWindow.GetWindow(typeof(Images));
ImagesUI.Init((Images)images);

window.minSize = new Vector2(MinimumWidth, window.minSize.y);
window.minSize = new Vector2(window.minSize.x, MinimumHeight);
var images = (Images)GetWindow(typeof(Images));
ImagesUI.Init(images);
}

private void OnGUI()
Expand All @@ -37,42 +41,45 @@ private void OnGUI()

private void OnDestroy()
{
ImagesUI.ClearSelectedTexture();
ImagesUI.OnClose();
ImagesUI.CloseSelectedTextureSection();
DataCache.instance.ClearAllImageData();
}
private static void GetInferencesData()

private void OnBecameVisible()
{
string selectedModelId = EditorPrefs.GetString("SelectedModelId");
if (selectedModelId.Length < 2)
{
Debug.LogError("Please select a model first.");
return;
}
isVisible = true;
}

string paginationTokenString = EditorPrefs.GetString(PaginationTokenKey,"");
if (paginationTokenString != "")
{
paginationTokenString = "&paginationToken=" + paginationTokenString;
}
private void OnBecameInvisible()
{
isVisible = false;
}

public static void GetInferencesData(Action callback_OnDataGet = null) //why get inferences instead of getting the assets ??
{
string request = $"inferences";
if (!string.IsNullOrEmpty(lastPageToken))
request = $"inferences?paginationToken={lastPageToken}";

ApiClient.RestGet($"inferences?nextPaginationToken={_paginationToken}", response =>
ApiClient.RestGet(request, response =>
{
var inferencesResponse = JsonConvert.DeserializeObject<InferencesResponse>(response.Content);
_paginationToken = inferencesResponse.nextPaginationToken;

lastPageToken = inferencesResponse.nextPaginationToken;

if (inferencesResponse.inferences[0].status == "failed")
{
Debug.LogError("Api Response: Status == failed, Try Again..");
}

_imageDataList.Clear();
ImagesUI.textures.Clear();
List<ImageDataStorage.ImageData> imageDataDownloaded = new List<ImageDataStorage.ImageData>();

foreach (var inference in inferencesResponse.inferences)
{
foreach (var image in inference.images)
{
_imageDataList.Add(new ImageDataStorage.ImageData
imageDataDownloaded.Add(new ImageDataStorage.ImageData
{
Id = image.id,
Url = image.url,
Expand All @@ -81,69 +88,66 @@ private static void GetInferencesData()
Steps = inference.parameters.numInferenceSteps,
Size = new Vector2(inference.parameters.width,inference.parameters.height),
Guidance = inference.parameters.guidance,
Scheduler = "Default",
Scheduler = "Default", //TODO : change this to reflect the scheduler used for creating this image
Seed = image.seed,
CreatedAt = inference.createdAt,
modelId = inference.modelId
});
}
}

ImagesUI.SetFirstPage();
ImagesUI.UpdatePage();
imageDataList.AddRange(imageDataDownloaded);
foreach (ImageDataStorage.ImageData imageData in imageDataList)
{
FetchTextureFor(imageData);
}
callback_OnDataGet?.Invoke();
});
}

public void DeleteImageAtIndex(int selectedTextureIndex)

/// <summary>
/// Fetch a texture for a specific ImageData
/// </summary>
private static void FetchTextureFor(ImageDataStorage.ImageData _image, Action callback_OnTextureGet = null)
{
ImagesUI.textures.RemoveAt(selectedTextureIndex);
CommonUtils.FetchTextureFromURL(_image.Url, texture =>
{
_image.texture = texture;
callback_OnTextureGet?.Invoke();
});
}

string imageId = _imageDataList[selectedTextureIndex].Id;
string modelId = EditorPrefs.GetString("SelectedModelId", "");
string inferenceId = _imageDataList[selectedTextureIndex].InferenceId;
/// <summary>
///
/// </summary>
/// <param name="_id">The id of the image you want to delete</param>
public void DeleteImage(string _id)
{
var imageData = Images.GetImageDataById(_id); //try to get image from Images
if (imageData == null)
imageData = DataCache.instance.GetImageDataById(_id); //try to get from Datacache (if it has just been prompted)
if (imageData == null)
return;

Debug.Log("Requesting image deletion please wait..");

string url = $"models/{modelId}/inferences/{inferenceId}/images/{imageId}";

string url = $"models/{imageData.modelId}/inferences/{imageData.InferenceId}/images/{imageData.Id}";
ApiClient.RestDelete(url,null);
imageDataList.Remove(imageData);

if(DataCache.instance.DoesImageIdExist(_id)) //also delete from Datacache if it's there
DataCache.instance.RemoveImageDataById(_id);

Repaint();
}

internal void RemoveBackgroundForImageAtIndex(int selectedTextureIndex)
public static ImageDataStorage.ImageData GetImageDataById(string _id)
{
string dataUrl = CommonUtils.Texture2DToDataURL(ImagesUI.textures[selectedTextureIndex]);
string fileName =CommonUtils.GetRandomImageFileName();
string param = $"{{\"image\":\"{dataUrl}\",\"name\":\"{fileName}\",\"format\":\"png\",\"returnImage\":\"false\"}}";

Debug.Log($"Requesting background removal, please wait..");

ApiClient.RestPut("images/erase-background",param, response =>
{
if (response.ErrorException != null)
{
Debug.LogError($"Error: {response.ErrorException.Message}");
}
else
{
Debug.Log($"Response: {response.Content}");

try
{
dynamic jsonResponse = JsonConvert.DeserializeObject(response.Content);
string imageUrl = jsonResponse.asset.url;
return imageDataList.Find(x => x.Id == _id);
}

CommonUtils.FetchTextureFromURL(imageUrl, texture =>
{
CommonUtils.SaveTextureAsPNG(texture);
});
}
catch (Exception ex)
{
Debug.LogError("An error occurred while processing the response: " + ex.Message);
}
}
});
public static Texture2D GetTextureByImageId(string _id)
{
return imageDataList.Find(x => x.Id == _id).texture;
}

}
}
Loading
Loading