@page "/aiart" @using OpenAI_API @using OpenAI_API.Chat @using OpenAI_API.Models @using DataAccess.Data @using DataAccess.Models @using KIKunstKirstenKlöckner.Data @using System.Diagnostics @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: @* Zusätzliche Optionen *@ Temperature: @_temperature Resolution: x @* *@ await GenerateImagesAsync())>Generate Die Idee, die gemalt wird: @_imageIdea Verändere hier dein Bild durch Worte: await UpdateImagesAsync())>Generate @_imagePromts[0]
Model: @_bildInfos[0]?.ImageModel
@_imagePromts[1]
Model: @_bildInfos[1]?.ImageModel
@_imagePromts[2]
Model: @_bildInfos[2]?.ImageModel
@_imagePromts[3]
Model: @_bildInfos[3]?.ImageModel
@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 BildInfoModel?[] _bildInfos = new BildInfoModel?[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? _imageWidth = null; private int? _imageHeight = null; private string _userIdea = ""; private string _updateRequest = ""; private OpenAIAPI _openAiApi; private Conversation? _conversation; private string _basePrompt; private string _ideaPrompt; private string _imageUrl; private WunschInfoModel? _wunschInfo; async Task UpdateBusyMessage(string newMessage) { BusyMessage = newMessage; await InvokeAsync(StateHasChanged); } private string _openAiApiKey = ""; class ModelInfo { public string Name { get; set; } public string StableDiffusionModel { get; set; } public string PromptFormat { get; set; } } private List _imageModels; private ModelInfo? _selectedImageModel = null; protected override async Task OnInitializedAsync() { _openAiApiKey = Config.GetValue("API:OpenAI"); _openAiApi = new OpenAIAPI(_openAiApiKey); _imageModels = Config.GetSection("ImageModels").Get>(); //_selectedImageModel = _imageModels[0]; 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 + " " + _userIdea); _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) { // 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] = RequestImagePromptAndGenerateImageAsync(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 RequestImagePromptAndGenerateImageAsync(int index, WunschInfoModel wunschInfo) { ModelInfo imageModel = _selectedImageModel ?? _imageModels[Random.Shared.Next(_imageModels.Count)]; // 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 = string.Format(imageModel.PromptFormat, 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); BildInfoModel? bildInfo = await GenerateImageAsync(imagePrompt, imageModel.StableDiffusionModel, wunschInfo); // TODO: Fehler im UI anzeigen (zur Zeit bleibt einfach Ladebalken) _imageUrls[index] = bildInfo?.Dateiname; _bildInfos[index] = bildInfo; _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, string modelName, WunschInfoModel wunschInfo) { try { BildInfoModel? bildInfo = await ImageGenerator.GenerateImageAsync(imagePrompt, modelName, wunschInfo, _imageWidth, _imageHeight); // Kein Bild -> Fehler if (bildInfo == 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) { bildInfo = await ImageGenerator.GenerateImageAsync(imagePrompt, modelName, wunschInfo, _imageWidth, _imageHeight); } } return bildInfo; } 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. /// private async Task GenerateImagesAsync() { _progressVisible = true; _buttonVisible = false; ClearOldGeneration(); amountOfAddons = maxAddons; _addonsVisible = false; _bothVisible = _buttonVisible && _addonsVisible; await UpdateBusyMessage("Kirstens Assistent zerbricht sich über deine Idee den Kopf..."); await RequestImageIdeaAsync(); await UpdateBusyMessage("Kirstens Assistent hat eine Idee! Er wird sie nun malen..."); _wunschInfo = new() { BildBeschreibung = _imageIdea, BildPrompt = "Individuelle Bild Prompts", Datum = DateTime.Now, GPTModel = _conversation!.Model, Wunsch = _userIdea, 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; } string requestImagePrompt = await File.ReadAllTextAsync($"{Directory.GetCurrentDirectory()}{@"/wwwroot/image_prompt.txt"}"); await RequestImagesAsync(_wunschInfo, requestImagePrompt); _progressVisible = false; _buttonVisible = true; if (amountOfAddons > 0) { _addonsVisible = true; _bothVisible = _buttonVisible && _addonsVisible; await InvokeAsync(StateHasChanged); } else { _addonsVisible = false; _bothVisible = false; } } private async Task UpdateImagesAsync() { Debug.Assert(_conversation != null); string updatePrompt = $"Gebe nun einen neuen Prompt unter berücksichtigung vorheriger Anweisungen und passe ihn folgender Maßen an: {_updateRequest}"; _wunschInfo = new() { BildBeschreibung = _updateRequest, BildPrompt = "Individuelle Bild Prompts", Datum = DateTime.Now, GPTModel = _conversation.Model, Wunsch = _userIdea, VorherigerWunsch = _wunschInfo!.Id }; 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, updatePrompt); } }