@page "/aiart" @using OpenAI_API @using OpenAI_API.Chat @using OpenAI_API.Models @using DataAccess.Data @using DataAccess.Models @using KIKunstKirstenKlöckner.Data @inject IConfiguration Config @inject TooltipService TooltipService @inject NotificationService NotificationService @inject DialogService DialogService @inject WunschInfoData WunschInfoData; @inject ImageGenerator ImageGenerator; AiArt

Wunschbilder von KI nur für dich

Nenne uns deinen Wunsch: Temperature: @_temperature Resolution: x await GenerateImagesAsync(true))>Generate Die Idee, die gemalt wird: @_imageIdea Verändere hier dein Bild durch Worte: await GenerateImagesAsync(false))>Generate @_imagePromts[0] @_imagePromts[1] @_imagePromts[2] @_imagePromts[3]
@code { /// /// Wenn wird GPT4 verwendet um die Idee zu interpretieren. /// private bool _useGpt4; private int maxAddons = 2; private int amountOfAddons = 0; // wird später geändert private bool _progressVisible = false; private bool _buttonVisible = true; private bool _addonsVisible = false; private bool _bothVisible = false; public string BusyMessage { get; set; } = "Initial Message"; private string?[] _imageUrls = new string?[4]; private string?[] _imagePromts = new string?[4]; private ImageState[] _imageStates = new ImageState[4]; enum ImageState { FadeOut, FadeIn } async Task ShowImageDialog(string imageUrl) { var result = await DialogService.OpenAsync("", ds => @
, new DialogOptions() { CloseDialogOnOverlayClick = true }); } void ShowTooltip(ElementReference elementReference, string text, TooltipOptions? options = null) => TooltipService.Open(elementReference, text, options); void ShowTemperatureTooltip(ElementReference elementReference) => TooltipService.Open(elementReference, ds => @
Gibt an, wie kreativ ChatGPT sein soll.
, new() { Position = TooltipPosition.Bottom, Duration = null}); private string _imageIdea = ""; private float _temperature = 0.9f; private int? width = 1024; private int? height = 1024; private string request = ""; private string addons = ""; private OpenAIAPI _openAiApi; private Conversation? _conversation; private string _basePrompt; private string _ideaPrompt; private string _imageUrl; //protected override async Task OnInitializedAsync() //{ // _basePrompt = await File.ReadAllTextAsync($"{Directory.GetCurrentDirectory()}{@"\wwwroot\prompt.txt"}"); //} async Task UpdateBusyMessage(string newMessage) { BusyMessage = newMessage; await InvokeAsync(StateHasChanged); } private string _openAiApiKey = ""; protected override async Task OnInitializedAsync() { _openAiApiKey = Config.GetValue("API:OpenAI"); _openAiApi = new OpenAIAPI(_openAiApiKey); await base.OnInitializedAsync(); } /// /// Setzt alle Felder zurück, die zu einem bestimmten Wunsch gehören. /// private void ClearOldGeneration() { // Bilder verbergen for (int i = 0; i < 4; i++) { _imageStates[i] = ImageState.FadeOut; _imagePromts[i] = null; } _imageIdea = ""; } /// /// Gibt ChatGPT den Wunsch und erlangt die Bild Idee. /// /// private async Task RequestImageIdeaAsync() { string ideaBasePrompt = await File.ReadAllTextAsync($"{Directory.GetCurrentDirectory()}{@"/wwwroot/idea_prompt.txt"}"); ChatRequest chatRequest = new ChatRequest { Temperature = _temperature, Model = _useGpt4 ? Model.GPT4 : Model.ChatGPTTurbo }; _conversation = _openAiApi.Chat.CreateConversation(chatRequest); // Wunsch an GPT senden und Bild Idee anfordern _conversation.AppendUserInput(ideaBasePrompt + " " + request); _imageIdea = await _conversation.GetResponseFromChatbotAsync(); } /// /// Fordert für mehrere Bilder Bild-Prompts an und generiert die dazugehörigen Bilder. /// private async Task RequestImagesAsync(WunschInfoModel wunschInfo) { string requestImagePrompt = await File.ReadAllTextAsync($"{Directory.GetCurrentDirectory()}{@"/wwwroot/image_prompt.txt"}"); // Nachricht mit Bildpromt anfrage senden _conversation!.AppendUserInput(requestImagePrompt); // Task-Liste, damit wir parallel Prompts anfordern und Bilder generieren können. Task[] imagePromts = new Task[4]; for (int i = 0; i < 4; i++) { imagePromts[i] = RequestPromptAndGenerateImageAsync(i, wunschInfo); } await Task.WhenAll(imagePromts); } /// /// Fordert einen Bild Prompt an und generiert ein Bild für diesen. /// /// Der Index des Bildes (für UI zeug) /// Der Wunsch für den ein Bild erzeugt wird. private async Task RequestPromptAndGenerateImageAsync(int index, WunschInfoModel wunschInfo) { // Bild Prompt von ChatGPT anfordern string imagePrompt = await _conversation!.GetResponseFromChatbotAsync(); // Keywords anhängen um Kirstens Stil zu aktivieren. // TODO: Gucken, ob wir dem Watercolor bums brauchen imagePrompt = "kkkk " + imagePrompt;// + " kkkk Watercolor + ink on paper, Pen drawing, wet-on-wet technique, dry-on-dry technique, dabbing technique. "; // Debug only: Promt anzeigen _imagePromts[index] = imagePrompt; await InvokeAsync(StateHasChanged); string? imageUrl = await GenerateImageAsync(imagePrompt, wunschInfo); // TODO: Fehler im UI anzeigen (zur Zeit bleibt einfach Ladebalken) _imageUrls[index] = imageUrl; _imageStates[index] = ImageState.FadeIn; await InvokeAsync(StateHasChanged); } /// /// Erzeugt ein Bild für den gegebenen Prompt und Wunsch. /// /// Der Bild Prompt /// Der Wunsch. /// Die URL, falls das Bild generiert wurde; oder null, wenn kein Bild generiert werden konnte. private async Task GenerateImageAsync(string imagePrompt, WunschInfoModel wunschInfo) { try { string? imageUrl = (await ImageGenerator.GenerateImageAsync(imagePrompt, wunschInfo, width, height))?.Dateiname; // Kein Bild -> Fehler if (imageUrl == null) { bool? retry = await DialogService.Confirm( "Leider konnte das Bild nicht gemalt werden. Möchtest du es noch eimal versuchen?", "Ups, ein Fehler ist aufgetreten...", new ConfirmOptions { OkButtonText = "Ja", CancelButtonText = "Nein" }); if (retry == true) { imageUrl = (await ImageGenerator.GenerateImageAsync(imagePrompt, wunschInfo, width, height))?.Dateiname; } } return imageUrl; } catch (Exception e) { NotificationService.Notify(new NotificationMessage() { Summary = "Es ist ein Fehler beim Erzeugen der Bilder aufgetreten, bitte versuche es erneut." }); } return null; } /// /// Generiert Bilder oder aktualisiert sie mit dem neuen Prompt. /// /// Wenn , werden neue Bilder generiert; sonst wird die vorhandene Idee bearbeitet. private async Task GenerateImagesAsync(bool generateNewImage) { // Der Dialog blokiert so lange, wie der er offen ist, deshalb dürfen wir hier nicht warten, da wir sonst nie mit der Arbeit anfangen... //Task busyDialog = ShowBusyDialog(); _progressVisible = true; _buttonVisible = false; if (_conversation == null || generateNewImage) { ClearOldGeneration(); amountOfAddons = maxAddons; _addonsVisible = false; _bothVisible = _buttonVisible && _addonsVisible; await UpdateBusyMessage("Kirstens Assistent zerbricht sich über deine Idee den Kopf..."); await RequestImageIdeaAsync(); } else { throw new NotImplementedException("Verändern von Idees ist nicht implementiert"); // if (amountOfAddons > 0) // { // amountOfAddons--; // _bothVisible = _buttonVisible && _addonsVisible; // await UpdateBusyMessage("Kirstens Assistent passt das Bild an deine Wünsche an..."); // string addonsPrompt1 = "Erstelle einen neuen Prompt auf englisch mit den gleichen Restriktionen auf Basis des Alten mit folgender Anpassung: "; // string addonsPrompt2 = ". Denke daran nur den Prompt zu generieren und noch keine Beschreibung oder ähnliches."; // _conversation.AppendUserInput(addonsPrompt1 + addons + addonsPrompt2); // } } await UpdateBusyMessage("Kirstens Assistent hat eine Idee! Er wird sie nun malen..."); WunschInfoModel wunschInfo = new() { BildBeschreibung = _imageIdea, BildPrompt = "Individuelle Bild Prompts", Datum = DateTime.Now, GPTModel = _conversation.Model, Wunsch = request, // TODO: Wenn wir Wünsche überarbeiten können wir hier diesen hier referenzieren VorherigerWunsch = null }; try { await WunschInfoData.AddWunschInfoAsync(wunschInfo); } catch (Exception e) { NotificationService.Notify(new NotificationMessage() { Summary = "Es ist ein Fehler aufgetreten, bitte versuche es erneut." }); return; } await RequestImagesAsync(wunschInfo); _progressVisible = false; _buttonVisible = true; if (amountOfAddons > 0) { _addonsVisible = true; _bothVisible = _buttonVisible && _addonsVisible; await InvokeAsync(StateHasChanged); } else { _addonsVisible = false; _bothVisible = false; } } }