Compare commits

..

1 Commits

Author SHA1 Message Date
Meiko Remiorz 247c913051 redesign vom bilder generieren 2023-10-11 18:31:25 +02:00
52 changed files with 822 additions and 1546 deletions

View File

@ -1,4 +0,0 @@
root = true
[*]
charset = utf-8

View File

@ -1,13 +0,0 @@
# Default ignored files
/shelf/
/workspace.xml
# Rider ignored files
/modules.xml
/.idea.KIKunstKirstenKlöckner.iml
/contentModel.xml
/projectSettingsUpdater.xml
# Editor-based HTTP Client requests
/httpRequests/
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml

View File

@ -1 +0,0 @@
KIKunstKirstenKlöckner

View File

@ -1,19 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="DataSourceManagerImpl" format="xml" multifile-model="true">
<data-source source="LOCAL" name="Nackenserver" uuid="2da1b5f0-41db-4b4f-adbd-3ec21fc94746">
<driver-ref>sqlserver.jb</driver-ref>
<synchronize>true</synchronize>
<jdbc-driver>com.jetbrains.jdbc.sqlserver.SqlServerDriver</jdbc-driver>
<jdbc-url>Server=127.0.0.1,1433;Database=KiKunst</jdbc-url>
<working-dir>$ProjectFileDir$</working-dir>
</data-source>
<data-source source="LOCAL" name="KiKunstDatenbank@85.215.58.36" uuid="df248d03-0de1-4e34-86bf-d38047939693">
<driver-ref>sqlserver.jb</driver-ref>
<synchronize>true</synchronize>
<jdbc-driver>com.jetbrains.jdbc.sqlserver.SqlServerDriver</jdbc-driver>
<jdbc-url>Server=85.215.58.36;Database=KiKunstDatenbank</jdbc-url>
<working-dir>$ProjectFileDir$</working-dir>
</data-source>
</component>
</project>

View File

@ -1,6 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Encoding">
<file url="file://$PROJECT_DIR$/KIKunstKirstenKlöckner/Program.cs" charset="windows-1252" />
</component>
</project>

View File

@ -1,8 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="UserContentModel">
<attachedFolders />
<explicitIncludes />
<explicitExcludes />
</component>
</project>

View File

@ -1,38 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="SqlDataSourceStorage">
<option name="dataSources">
<list>
<State>
<option name="id" value="01ff5a47-63ce-4ef8-aed7-c9f2f9f5c726" />
<option name="name" value="KiKunstDatenbank" />
<option name="dbmsName" value="MSSQL" />
<option name="urls">
<array>
<option value="file://$PROJECT_DIR$/KiKunstDatenbank/dpo/Tables/BildInfo.sql" />
<option value="file://$PROJECT_DIR$/KiKunstDatenbank/dpo/Tables/WunschInfo.sql" />
<option value="file://$PROJECT_DIR$/KiKunstDatenbank/dpo/StoredProcedures/spBildInfo_Insert.sql" />
<option value="file://$PROJECT_DIR$/KiKunstDatenbank/dpo/StoredProcedures/spWunschInfo_Insert.sql" />
<option value="file://$PROJECT_DIR$/KiKunstDatenbank/dpo/StoredProcedures/spBildInfo_UpdateFileName.sql" />
<option value="file://$PROJECT_DIR$/KiKunstDatenbank/dpo/StoredProcedures/spBildInfo_GetAll.sql" />
<option value="file://$PROJECT_DIR$/KiKunstDatenbank/dpo/StoredProcedures/spWunschInfo_Get.sql" />
</array>
</option>
<option name="remarks" value="Database Project" />
<option name="outPath" value="$PROJECT_DIR$/KiKunstDatenbank" />
<option name="codeStyleName" value="Visual Studio Database Project" />
<option name="outLayout" value="File per object by schema.groovy" />
<option name="scriptOptions">
<map>
<entry key="ConstraintContext" value="CONSTRAINT_IN_TABLE" />
<entry key="MsVsDdlCompatibility" value="1" />
<entry key="QualifyWithSchema" value="ALWAYS" />
<entry key="Reformat" value="1" />
<entry key="UseSemicolon" value="1" />
</map>
</option>
</State>
</list>
</option>
</component>
</project>

View File

@ -1,12 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="SqlDialectMappings">
<file url="file://$PROJECT_DIR$/KiKunstDatenbank/dpo/StoredProcedures/spBildInfo_GetAll.sql" dialect="TSQL" />
<file url="file://$PROJECT_DIR$/KiKunstDatenbank/dpo/StoredProcedures/spBildInfo_Insert.sql" dialect="TSQL" />
<file url="file://$PROJECT_DIR$/KiKunstDatenbank/dpo/StoredProcedures/spBildInfo_UpdateFileName.sql" dialect="TSQL" />
<file url="file://$PROJECT_DIR$/KiKunstDatenbank/dpo/StoredProcedures/spWunschInfo_Get.sql" dialect="TSQL" />
<file url="file://$PROJECT_DIR$/KiKunstDatenbank/dpo/StoredProcedures/spWunschInfo_Insert.sql" dialect="TSQL" />
<file url="file://$PROJECT_DIR$/KiKunstDatenbank/dpo/Tables/BildInfo.sql" dialect="TSQL" />
<file url="file://$PROJECT_DIR$/KiKunstDatenbank/dpo/Tables/WunschInfo.sql" dialect="TSQL" />
</component>
</project>

View File

@ -1,6 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="" vcs="Git" />
</component>
</project>

View File

@ -19,7 +19,7 @@ public class BildInfoData
/// Fügt die gegebene BildInfo zur Datenbank hinzu und aktualisiert das <see cref="BildInfoModel.Id"/>-Feld mit dem entsprechenden Wert.
/// </summary>
/// <param name="bildInfo">Die BildInfo, die zur Datenbank hinzugefügt werden soll.</param>
public async Task InsertBildInfoAsync(BildInfoModel bildInfo)
public async Task AddBildInfoAsync(BildInfoModel bildInfo)
{
var id = await _db.LoadData<int, BildInfoModel>("dbo.spBildInfo_Insert", bildInfo);
bildInfo.Id = id.Single();

View File

@ -1,16 +1,15 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<TargetFramework>net7.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<LangVersion>12</LangVersion>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Dapper" Version="2.1.35" />
<PackageReference Include="Microsoft.Extensions.Configuration.Abstractions" Version="8.0.0" />
<PackageReference Include="System.Data.SqlClient" Version="4.8.6" />
<PackageReference Include="Dapper" Version="2.1.4" />
<PackageReference Include="Microsoft.Extensions.Configuration.Abstractions" Version="7.0.0" />
<PackageReference Include="System.Data.SqlClient" Version="4.8.5" />
</ItemGroup>
</Project>

View File

@ -7,5 +7,4 @@ public class BildInfoModel
public string Dateiname { get; set; }
public string ImageModel { get; set; }
public int WunschId { get; set; }
public string Prompt { get; set; }
}

View File

@ -8,9 +8,4 @@ public class WunschInfoModel
public string BildBeschreibung { get; set; }
public DateTime Datum { get; set; }
public string GPTModel { get; set; }
/// <summary>
/// Id eines vorherigen Wunsches, z.B. wenn ein Wunsch überarbeitet wird, wird der original wunsch hier referenziert.
/// Ist <see langword="null"/> für den initialien Wunsch.
/// </summary>
public int? VorherigerWunsch { get; set; }
}

View File

@ -7,7 +7,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "KIKunstKirstenKlöckner", "
EndProject
Project("{00D1A9C2-B5F0-4AF3-8072-F6C62B433612}") = "KiKunstDatenbank", "KiKunstDatenbank\KiKunstDatenbank.sqlproj", "{A19CD19A-FE5B-4D4E-896B-DCC43B45F734}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DataAccess", "DataAccess\DataAccess.csproj", "{0880FD07-236B-42C1-9CA3-2A6F695A623C}"
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DataAccess", "DataAccess\DataAccess.csproj", "{0880FD07-236B-42C1-9CA3-2A6F695A623C}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution

View File

@ -1,14 +1,4 @@
@using OpenAI_API
@using OpenAI_API.Chat
@using OpenAI_API.Models
@using Microsoft.AspNetCore.Components
@using KIKunstKirstenKlöckner.Data
@inject IConfiguration Config
@inject NavigationManager NavigationManager
<Router AppAssembly="@typeof(App).Assembly">
<Router AppAssembly="@typeof(App).Assembly">
<Found Context="routeData">
<RouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)" />
<FocusOnNavigate RouteData="@routeData" Selector="h1" />
@ -16,54 +6,7 @@
<NotFound>
<PageTitle>Not found</PageTitle>
<LayoutView Layout="@typeof(MainLayout)">
<p style="text-align:center;" role="alert">@_text</p>
@* @_mus *@
<p role="alert">Sorry, there's nothing at this address.</p>
</LayoutView>
</NotFound>
</Router>
@code {
private MarkupString _mus = new MarkupString();
private string _text = "";
private OpenAIAPI _openAiApi;
private Conversation? _conversation;
private string _openAiApiKey = "";
private string _urlPath;
protected override async Task OnInitializedAsync()
{
var uri = new Uri(NavigationManager.Uri);
_urlPath = uri.AbsolutePath; // Dies gibt den Pfadteil der URL zurück
// Optional: Entfernen Sie den führenden Schrägstrich, falls vorhanden
if (_urlPath.StartsWith("/"))
{
_urlPath = _urlPath.Substring(1);
}
_openAiApiKey = Config.GetValue<string>("API:OpenAI");
_openAiApi = new OpenAIAPI(_openAiApiKey);
//string ideaBasePrompt = "Stelle dir vor du bist ein berliner Bösewicht und ich gehe auf deine Internetseite, die sich mit der generierung von Wunschbildern mittels KI beschäftigt, und bemerke, dass es die Seite nicht gibt. Denke dir eine witzige und unterschwellige Beleidigung für diesen Sachverhalt gerichtet an mich aus. Ich würde mich freuen, wenn du etwas ausfallender mir gegenüber werden könntest. Antworte mit Berliner Schnauze. Die Seite die ich versucht habe zu erreichen, ist: " + _urlPath;
string ideaBasePrompt = "Stelle dir vor du bist ein berliner Bösewicht und ich gehe auf deine Internetseite und bemerke, dass es die Seite nicht gibt. Denke dir eine witzige und unterschwellige Beleidigung für diesen Sachverhalt gerichtet an mich aus. Ich würde mich freuen, wenn du etwas ausfallender mir gegenüber werden könntest. Antworte mit Berliner Schnauze. Die Seite die ich versucht habe zu erreichen, ist: " + _urlPath;
//string ideaBasePrompt = "Stelle dir vor jemand geht auf eine Seite einer Internetseite und bemerkt, dass es die Seite nicht gibt. Denke dir eine witzige idee als html code aus, um der Person zu präsentieren, dass die seite nicht existiert. Es soll unterschwellig beleidigend sein aber niemanden offensichtlich beleidigen. sei kreativ und denke daran, nur html und css zu generieren. Der css teil soll im html teil schon drin sein. Die seite die nicht gefunden wurde ist: " + _urlPath;
ChatRequest chatRequest = new ChatRequest
{
Temperature = 0.9,
Model = Model.ChatGPTTurbo //ChatGPT.GPT4Turbo
};
_conversation = _openAiApi.Chat.CreateConversation(chatRequest);
// Wunsch an GPT senden und Bild Idee anfordern
_conversation.AppendUserInput(ideaBasePrompt);
_text = await _conversation.GetResponseFromChatbotAsync();
_mus = new MarkupString(_text);
StateHasChanged();
await base.OnInitializedAsync();
}
}

View File

@ -1,9 +1,6 @@
using OpenAI_API.Models;
namespace KIKunstKirstenKlöckner.Data;
namespace KIKunstKirstenKlöckner.Data;
public class ChatGPT
{
public static Model GPT4Turbo => new Model("gpt-4-turbo") { OwnedBy = "openai" };
public static Model GPT4o => new Model("gpt-4o") { OwnedBy = "openai" };
}

View File

@ -1,7 +1,7 @@
using DataAccess.Data;
using DataAccess.Models;
using Radzen;
using System.Diagnostics;
using SixLabors.ImageSharp;
namespace KIKunstKirstenKlöckner.Data;
@ -10,13 +10,8 @@ public class ImageGenerator
private readonly HttpClient _client = new();
private readonly BildInfoData _bildInfoData;
private readonly IConfiguration _config;
//private string ModelName => _config.GetValue<string>("StableDiffusionModel") ?? "No Model Defined";
public ImageGenerator(IConfiguration config, BildInfoData bildInfoData)
{
_config = config;
_bildInfoData = bildInfoData;
string? inferenceApiKey = config.GetValue<string>("API:HF_Inference");
@ -26,19 +21,13 @@ public class ImageGenerator
}
/// <summary>
/// Geneiert ein Bild für den gegebenen Wunsch.
/// Geneiert das Bild für den aktuellen <see cref="_imagePrompt"/>
/// </summary>
/// <param name="imagePrompt">Der Prompt für den das Bild erzeugt wird.</param>
/// <param name="wunschInfo">Der Wunsch zu dem ein Bild generiert werden soll.</param>
/// <param name="width">Die breite des zu generierenden Bildes. <see langword="null"/> für Standardbreite des Modells</param>
/// <param name="height">Die höhe des zu generierenden Bildes. <see langword="null"/> für Standardhöhe des Modells</param>
/// <param name="negativePromt">Begriffe, die explizit nicht generiert werden sollen.</param>
/// <returns>Die BildInfo des generierten Bildes; oder null, wenn ein Fehler auftrat.</returns>
public async Task<BildInfoModel?> GenerateImageAsync(string imagePrompt, string modelName, WunschInfoModel wunschInfo, int? width = null, int? height = null, string negativePromt = "")
public async Task<string?> GenerateImageAsync(string prompt, string negativePromt, int? width, int? height, WunschInfoModel wunschInfo, bool isRetry = false)
{
var postData = new
{
inputs = imagePrompt,
inputs = prompt,
parameters = new
{
negative_prompt = negativePromt, //"photorealistic, highly detailed, 8K, portrait",
@ -47,11 +36,9 @@ public class ImageGenerator
},
options = new
{
// https://huggingface.co/docs/api-inference/detailed_parameters
// Cache deaktivieren, damit Huggingface für den selben Prompt unterschiedliche Ergebnisse liefert
use_cache = false,
// Ignoriert 503-Fehler. Diese treten auf wenn Hugging Face das Model noch nicht geladen hat.
// Mit true ignorieren wir den Fehler und schlagen erst fehl, wenn wir einen timeout haben.
// Erst wenn wir bereits in einem retry sind warten wir implizit auf das Model. (ignoriert quasi 503-Fehler)
wait_for_model = true
}
};
@ -60,6 +47,9 @@ public class ImageGenerator
try
{
//const string modelName = "Nacken/kkkk-sdxl-5000";
const string modelName = "Nacken/kkk-sdxl-18000";
var inferenceModelUrl = $"https://api-inference.huggingface.co/models/{modelName}";
var response = await _client.PostAsync(inferenceModelUrl, content);
@ -68,21 +58,29 @@ public class ImageGenerator
{
await using Stream imageStream = await response.Content.ReadAsStreamAsync();
using Image image = await Image.LoadAsync(imageStream);
DateTime imageDate = DateTime.Now;
BildInfoModel bildInfo = new()
{
// Die tatsächliche Url wird in SaveImageStreamAsync gesetzt.
Dateiname = "PlaceHolder",
Datum = imageDate,
ImageModel = modelName,
WunschId = wunschInfo.Id,
Prompt = imagePrompt
WunschId = wunschInfo.Id
};
await SaveImageStreamAsync(imageStream, bildInfo);
await _bildInfoData.AddBildInfoAsync(bildInfo);
return bildInfo;
string imgUrl = $"generated_images/Image_{bildInfo.Id}.jpg";
string mapPath = $"./wwwroot/{imgUrl}";
await image.SaveAsJpegAsync(mapPath);
bildInfo.Dateiname = imgUrl;
await _bildInfoData.UpdateBildInfoDateinameAsync(bildInfo);
return imgUrl;
}
else
{
@ -104,26 +102,4 @@ public class ImageGenerator
return null;
}
}
/// <summary>
/// Speichert den Inhalt des gegebenen Datenstroms als Bild ab.
/// </summary>
/// <param name="dataStream">Der Datenstrom, der das Bild enthält.</param>
/// <param name="bildInfo">Die BildInfo des Bildes. Der Dateiname wird nach dem Speichern aktualisiert.</param>
private async Task SaveImageStreamAsync(Stream dataStream, BildInfoModel bildInfo)
{
using Image image = await Image.LoadAsync(dataStream);
// Speichert BildInfo in der Datenbank, aktualisiert Id der bildInfo
await _bildInfoData.InsertBildInfoAsync(bildInfo);
string imageUrl = $"generated_images/Image_{bildInfo.Id}.jpg";
string imageFilePath = $"./wwwroot/{imageUrl}";
await image.SaveAsJpegAsync(imageFilePath);
// Speichert den geänderten Dateinamen in der Datenbank
bildInfo.Dateiname = imageUrl;
await _bildInfoData.UpdateBildInfoDateinameAsync(bildInfo);
}
}

View File

@ -1,23 +0,0 @@
namespace KIKunstKirstenKlöckner.Extensions
{
public static class ListExtension
{
public static IEnumerable<T> PickRandom<T>(this List<T> list, int n)
{
if (list.Count == 0)
{
yield break;
}
if (n <= 0)
{
throw new ArgumentException("n must be greater than 0: ", nameof(n));
}
for (int i = 0; i < n; i++)
{
int index = Random.Shared.Next(list.Count);
yield return list[index];
}
}
}
}

View File

@ -1,22 +1,23 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<TargetFramework>net7.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<UserSecretsId>c1bf616d-d992-465d-91b1-995a57ba483d</UserSecretsId>
<DockerDefaultTargetOS>Linux</DockerDefaultTargetOS>
<LangVersion>12</LangVersion>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.21.0" />
<PackageReference Include="OpenAI" Version="1.11.0" />
<PackageReference Include="Radzen.Blazor" Version="4.33.1" />
<PackageReference Include="HuggingFace" Version="0.2.3" />
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.18.1" />
<PackageReference Include="OpenAI" Version="1.7.2" />
<PackageReference Include="Radzen.Blazor" Version="4.14.4" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="SixLabors.ImageSharp" Version="3.1.4" />
<Folder Include="wwwroot\NewFolder\" />
<PackageReference Include="SixLabors.ImageSharp" Version="3.0.1" />
</ItemGroup>
<ItemGroup>

View File

@ -6,119 +6,34 @@
@using DataAccess.Data
@using DataAccess.Models
@using KIKunstKirstenKlöckner.Data
@using KIKunstKirstenKlöckner.Extensions
@using System.Diagnostics
@inject IJSRuntime JSRuntime
@inject IConfiguration Config
@inject TooltipService TooltipService
@inject NotificationService NotificationService
@inject DialogService DialogService
@inject ImageGenerator ImageGenerator;
@inject BildInfoData BildInfoData;
@* @inject AiArtPageData AiArtData; *@
@inject WunschInfoData WunschInfoData;
@inject ImageGenerator ImageGenerator;
@implements IAsyncDisposable
<PageTitle>AiArt</PageTitle>
<style>
.invisible-rectangle {
width: 100%;
height: 600px;
opacity: 0;
background-color: transparent;
pointer-events: none;
}
.invisible-rectangle-small {
width: 100%;
height: 100px;
opacity: 0;
background-color: transparent;
pointer-events: none;
}
</style>
<PageTitle>Wunschbild Generator</PageTitle>
<section class="about_section" style="background-image: url('images/5KeineAngstvorFehlern2014.jpeg'); background-size: cover; background-repeat: no-repeat; background-blend-mode:lighten">
<div class="hero_area hero-area-visible">
<!-- slider section -->
<section class="slider_section" style="background-image: url('images/3730Kilo2015.jpeg'); background-size: cover; background-repeat: no-repeat; background-blend-mode:lighten">
<div class="container">
<div class="row">
<div class="col-md-6 ">
<div class="detail_box">
<h1>
Hier werden <br>
deine Wünsche <br>
Wirklichkeit
</h1>
<p>
Weiter unten findest du meinen Assistenten. Gebe ihm deinen Wunsch und er wird sich etwas tolles dazu überlegen. Es lohnt sich geduldig zu sein. <br>
Scrolle einfach nach unten!
</p>
</div>
</div>
<div class="col-lg-5 col-md-6 offset-lg-1">
<div class="img_content">
<div class="img_container">
<div id="carouselExampleControls" class="carousel slide" data-ride="carousel">
<div class="carousel-inner">
@if (_allBildInfos != null)
{
@foreach (var bildInfo in _allBildInfos)
{
if (_indexForCarusell == 0)
{
<div class="carousel-item active">
<div class="img-box">
<img src="@bildInfo.Dateiname"/>
</div>
</div>
}
else
{
<div class="carousel-item">
<div class="img-box">
<img src="@bildInfo.Dateiname"/>
</div>
</div>
}
_indexForCarusell++;
}
}
</div>
</div>
</div>
<a class="carousel-control-prev" href="#carouselExampleControls" role="button" data-slide="prev">
<span class="sr-only">Previous</span>
</a>
<a class="carousel-control-next" href="#carouselExampleControls" role="button" data-slide="next">
<span class="sr-only">Next</span>
</a>
</div>
</div>
</div>
</div>
</section>
<!-- end slider section -->
</div>
<div class="invisible-rectangle-small"></div>
<!-- start entry section -->
<section id="entrySection" class="section-animate-left" @ref="animatedEntrySection">
<section class="about_section layout_padding" style="background-image: url('images/5KeineAngstvorFehlern2014.jpeg'); background-size: cover; background-repeat: no-repeat; background-blend-mode:lighten">
<div class="container">
<RadzenStack Orientation="Orientation.Vertical" AlignItems="AlignItems.Center">
<h1>Wunschbilder von KI nur für dich</h1>
<RadzenText TextStyle="TextStyle.H2">Nenne uns deinen Wunsch:</RadzenText>
<RadzenTextBox @bind-Value=@_userIdea Placeholder="Dein Wunsch"/>
<RadzenStack Orientation="Orientation.Vertical" AlignItems="AlignItems.Center" Style="min-height:800px">
@* Zusätzliche Optionen *@
<RadzenText TextStyle="TextStyle.H2">Dein Wunsch:</RadzenText>
<RadzenStack Orientation="Orientation.Horizontal" AlignItems="AlignItems.Center">
<RadzenTextBox @bind-Value=@request Placeholder="..." />
<RadzenButton Visible=@_buttonVisible Click=@(async ()=> await GenerateImages(true))>Generieren</RadzenButton>
</RadzenStack>
<!--
<RadzenPanel AllowCollapse="true" Style="width: 500px;" Text="Mehr Optionen">
<ChildContent>
<RadzenCard class="rz-mt-4">
@ -136,57 +51,40 @@
AlignItems="AlignItems.Center" Wrap="FlexWrap.Wrap">
<RadzenText>Resolution:</RadzenText>
<RadzenStack Orientation="Orientation.Horizontal">
<RadzenNumeric ShowUpDown = "false" TValue = "int?" @bind-Value=@_imageWidth />
<RadzenNumeric ShowUpDown = "false" TValue = "int?" @bind-Value=@width />
x
<RadzenNumeric ShowUpDown = "false" TValue = "int?" @bind-Value=@_imageHeight />
<RadzenNumeric ShowUpDown = "false" TValue = "int?" @bind-Value=@height />
</RadzenStack>
</RadzenStack>
<RadzenRadioButtonList @bind-Value=@_usedGptModel TValue="GptModel" class="mb-5">
<Items>
<RadzenRadioButtonListItem Text="GPT-3.5 Turbo" Value="GptModel.Gpt3_5_turbo"
MouseEnter="@(args => ShowTooltip("Schnell aber nicht sonderlich clever.", args))"
MouseLeave="TooltipService.Close">
</RadzenRadioButtonListItem>
<RadzenRadioButtonListItem Text="GPT-4 Turbo" Value="GptModel.Gpt4_turbo"
MouseEnter="@(args => ShowTooltip("Etwas langsamer, aber recht klug.", args))"
MouseLeave="TooltipService.Close">
</RadzenRadioButtonListItem>
<RadzenRadioButtonListItem Text="GPT-4o" Value="GptModel.Gpt4o"
MouseEnter="@(args => ShowTooltip("Schnell, gut und günstig. Warum gibt es überhaupt eine Auswahlmöglichkeit?", args))"
MouseLeave="TooltipService.Close">
</RadzenRadioButtonListItem>
</Items>
</RadzenRadioButtonList>
@* <RadzenRadioButtonList Data="@_imageModels" @bind-Value=@_selectedImageModel TValue="ModelInfo" TextProperty="Name" class="mb-5"> *@
<RadzenRadioButtonList Data="@_imageModels" @bind-Value=@_selectedImageModel TValue="ModelInfo" TextProperty="Name" ValueProperty="" class="mb-5">
<Items>
<RadzenRadioButtonListItem Text="Zufällig" Value="@null" TValue="ModelInfo"
MouseEnter="@(args => ShowTooltip("Für jedes Bild wird zufällig ein Generator ausgewählt.", args))"
MouseLeave="TooltipService.Close"/>
</Items>
</RadzenRadioButtonList>
<RadzenStack Orientation="Orientation.Horizontal"
AlignItems="AlignItems.Center" Wrap="FlexWrap.Wrap">
<RadzenCheckBox @bind-Value=@_useGpt4>
Verwende Gibbidy 4
</RadzenCheckBox>
</RadzenStack>
</RadzenCard>
</ChildContent>
</RadzenPanel>
-->
<RadzenButton Visible=@_buttonVisible Click="@OnGenerateButtonClickAsync">Generate</RadzenButton>
</RadzenStack>
</div>
</section>
<!-- end entry section -->
<!-- start image section -->
<section id="imageSection">
<div class="container">
@if (_imageSectionVisible)
{
<section id="imageSection">
<RadzenStack Orientation="Orientation.Vertical" AlignItems="AlignItems.Center">
<RadzenText TextStyle="TextStyle.H4">Die Idee, die gemalt wird:</RadzenText>
<RadzenStack Orientation="Orientation.Vertical" Visible=@_promptVisible>
<RadzenCard class="rz-mt-4" Style="max-width: 500px">
<RadzenText>@_imagePrompt</RadzenText>
</RadzenCard>
<RadzenText TextStyle="TextStyle.H4">Interpretation deines Wunsches:</RadzenText>
<RadzenCard class="rz-mt-4" Style="width: 800px;">
<RadzenText>@_imageIdea</RadzenText>
</RadzenCard>
</RadzenStack>
<RadzenProgressBarCircular Visible=@_progressVisible ProgressBarStyle="ProgressBarStyle.Secondary" Value="100" ShowValue="false" Mode="ProgressBarMode.Indeterminate" />
<RadzenText Visible=@_progressVisible TextStyle="TextStyle.H6" Text=@BusyMessage></RadzenText>
@ -194,124 +92,43 @@
<RadzenImage Path=@_imageUrl></RadzenImage>
<RadzenText Visible=@_addonsVisible TextStyle="TextStyle.H2">Verändere hier dein Bild durch Worte:</RadzenText>
<RadzenTextBox Visible=@_addonsVisible @bind-Value=@_updateRequest Placeholder="z.B. Mehr Farben" />
<RadzenButton Visible=@_bothVisible Click=@(async ()=> await UpdateImagesAsync())>Generate</RadzenButton>
<RadzenTextBox Visible=@_addonsVisible @bind-Value=@addons Placeholder="z.B. Mehr Farben" />
<RadzenButton Visible=@_bothVisible Click=@(async ()=> await GenerateImages(false))>Generate</RadzenButton>
<RadzenCard>
<RadzenCard Visible="@_promptVisible">
<RadzenRow Style="width:24.5em" Gap="0.5rem" RowGap="0.5rem">
<RadzenColumn Size="6">
<FlippingImage ImageUrl="@_imageUrls[0]" HideImage="false"
Show="@(_imageStates[0] == ImageState.FadeIn)" FlipTo="FlippingImage.FlipDirection.Up"
Click="() => ShowImageDialog(_imageUrls[0])" />
<RadzenPanel AllowCollapse="true" Collapsed="true" Text="Info">
@_imagePromts[0]
<br />
Model: @_bildInfos[0]?.ImageModel
</RadzenPanel>
</RadzenColumn>
<RadzenColumn Size="6">
<FlippingImage ImageUrl="@_imageUrls[1]" HideImage="false"
Show="@(_imageStates[1] == ImageState.FadeIn)" FlipTo="FlippingImage.FlipDirection.Right" FlipDelay="200"
Click="() => ShowImageDialog(_imageUrls[1])" />
<RadzenPanel AllowCollapse="true" Collapsed="true" Text="Info">
@_imagePromts[1]
<br />
Model: @_bildInfos[1]?.ImageModel
</RadzenPanel>
</RadzenColumn>
<RadzenColumn Size="6">
<FlippingImage ImageUrl="@_imageUrls[2]" HideImage="false"
Show="@(_imageStates[2] == ImageState.FadeIn)" FlipTo="FlippingImage.FlipDirection.Left" FlipDelay="600"
Click="() => ShowImageDialog(_imageUrls[2])" />
<RadzenPanel AllowCollapse="true" Collapsed="true" Text="Info">
@_imagePromts[2]
<br />
Model: @_bildInfos[2]?.ImageModel
</RadzenPanel>
</RadzenColumn>
<RadzenColumn Size="6">
<FlippingImage ImageUrl="@_imageUrls[3]" HideImage="false"
Show="@(_imageStates[3] == ImageState.FadeIn)" FlipTo="FlippingImage.FlipDirection.Down" FlipDelay="400"
Click="() => ShowImageDialog(_imageUrls[3])" />
<RadzenPanel AllowCollapse="true" Collapsed="true" Text="Info">
@_imagePromts[3]
<br />
Model: @_bildInfos[3]?.ImageModel
</RadzenPanel>
</RadzenColumn>
</RadzenRow>
</RadzenCard>
</RadzenStack>
</section>
}
@if (!_imageSectionVisible)
{
<div class="invisible-rectangle"></div>
}
</div>
</section>
<!-- end image section -->
</RadzenStack>
</div>
</section>
@code {
// Animation stuff
private int _indexForCarusell = 0;
private ElementReference animatedEntrySection;
private List<ElementReference> animatedElements = new List<ElementReference>();
private Func<Task> removeScrollListener;
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender)
{
animatedElements.Add(animatedEntrySection);
removeScrollListener = await JSRuntime.InvokeAsync<Func<Task>>(
"initHeroAreaScrollAnimation"
);
await JSRuntime.InvokeVoidAsync("initScrollAnimations", animatedElements);
}
}
private bool isDisposed = false;
public async ValueTask DisposeAsync()
{
if (!isDisposed)
{
if (removeScrollListener != null)
{
await removeScrollListener.Invoke();
}
isDisposed = true;
}
}
private async Task OnGenerateButtonClickAsync()
{
_imageSectionVisible = true;
StateHasChanged();
await Task.Delay(100);
await JSRuntime.InvokeVoidAsync("scrollToElement", "imageSection");
await GenerateImagesAsync();
}
IEnumerable<BildInfoModel>? _allBildInfos;
enum GptModel
{
Gpt3_5_turbo,
Gpt4_turbo,
Gpt4o
}
/// <summary>
/// Das ChatGPT Model, das zur Erzeugung der Idee und Bild-Promts verwendet wird.
/// Wenn <see langword="true"/> wird GPT4 verwendet um die Idee zu interpretieren.
/// </summary>
private GptModel _usedGptModel = GptModel.Gpt3_5_turbo;
private bool _useGpt4;
private int maxAddons = 2;
private int amountOfAddons = 0; // wird später geändert
@ -319,13 +136,11 @@
private bool _buttonVisible = true;
private bool _addonsVisible = false;
private bool _bothVisible = false;
private bool _imageSectionVisible = false;
private bool _promptVisible = 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
@ -351,18 +166,14 @@
,
new() { Position = TooltipPosition.Bottom, Duration = null});
void ShowTooltip(string text, ElementReference elementReference) => TooltipService.Open(elementReference, ds =>
@<div>@text</div>
,
new() { Position = TooltipPosition.Bottom, Duration = null});
private string _imageIdea = "";
private string _imagePrompt = "";
private float _temperature = 0.9f;
private int? _imageWidth = null;
private int? _imageHeight = null;
private string _userIdea = "";
private string _updateRequest = "";
private int? width = 1024;
private int? height = 1024;
private string request = "";
private string addons = "";
private OpenAIAPI _openAiApi;
private Conversation? _conversation;
@ -371,7 +182,10 @@
private string _imageUrl;
private WunschInfoModel? _wunschInfo;
//protected override async Task OnInitializedAsync()
//{
// _basePrompt = await File.ReadAllTextAsync($"{Directory.GetCurrentDirectory()}{@"\wwwroot\prompt.txt"}");
//}
async Task UpdateBusyMessage(string newMessage)
{
@ -381,168 +195,61 @@
private string _openAiApiKey = "";
class ModelInfo
{
public string Name { get; set; }
public string StableDiffusionModel { get; set; }
public string PromptFormat { get; set; }
}
private List<ModelInfo> _imageModels;
private ModelInfo? _selectedImageModel = null;
protected override async Task OnInitializedAsync()
{
_allBildInfos = (await BildInfoData.GetAllBildInfosAsync()).ToList().PickRandom(10);
//await InvokeAsync(StateHasChanged);
_openAiApiKey = Config.GetValue<string>("API:OpenAI");
_openAiApi = new OpenAIAPI(_openAiApiKey);
_imageModels = Config.GetSection("ImageModels").Get<List<ModelInfo>>();
//_selectedImageModel = _imageModels[0];
await base.OnInitializedAsync();
}
/// <summary>
/// Setzt alle Felder zurück, die zu einem bestimmten Wunsch gehören.
/// </summary>
private void ClearOldGeneration()
{
// Bilder verbergen
for (int i = 0; i < 4; i++)
{
_imageStates[i] = ImageState.FadeOut;
_imagePromts[i] = null;
}
_imageIdea = "";
_imagePrompt = "";
}
/// <summary>
/// Gibt ChatGPT den Wunsch und erlangt die Bild Idee.
/// </summary>
/// <returns></returns>
private async Task RequestImageIdeaAsync()
{
string ideaBasePrompt = await File.ReadAllTextAsync($"{Directory.GetCurrentDirectory()}{@"/wwwroot/idea_prompt.txt"}");
string requestImagePrompt = await File.ReadAllTextAsync($"{Directory.GetCurrentDirectory()}{@"/wwwroot/test_prompt2.txt"}");
ChatRequest chatRequest = new ChatRequest
{
Temperature = _temperature,
Model = _usedGptModel switch
{
GptModel.Gpt3_5_turbo => Model.ChatGPTTurbo,
GptModel.Gpt4_turbo => ChatGPT.GPT4Turbo,
GptModel.Gpt4o => ChatGPT.GPT4o,
_ => throw new ArgumentOutOfRangeException()
}
Model = _useGpt4 ? Model.GPT4 : Model.ChatGPTTurbo
};
_conversation = _openAiApi.Chat.CreateConversation(chatRequest);
// Wunsch an GPT senden und Bild Idee anfordern
_conversation.AppendUserInput(ideaBasePrompt + " " + _userIdea);
_conversation.AppendUserInput(ideaBasePrompt + " " + request);
_imageIdea = await _conversation.GetResponseFromChatbotAsync();
}
/// <summary>
/// Fordert für mehrere Bilder Bild-Prompts an und generiert die dazugehörigen Bilder.
/// </summary>
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);
}
/// <summary>
/// Fordert einen Bild Prompt an und generiert ein Bild für diesen.
/// </summary>
/// <param name="index">Der Index des Bildes (für UI zeug)</param>
/// <param name="wunschInfo">Der Wunsch für den ein Bild erzeugt wird.</param>
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);
}
/// <summary>
/// Erzeugt ein Bild für den gegebenen Prompt und Wunsch.
/// </summary>
/// <param name="imagePrompt">Der Bild Prompt</param>
/// <param name="wunschInfo">Der Wunsch.</param>
/// <returns>Die URL, falls das Bild generiert wurde; oder null, wenn kein Bild generiert werden konnte.</returns>
private async Task<BildInfoModel?> 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;
// Bild Promt anfordern
_conversation.AppendUserInput(requestImagePrompt);
_imagePrompt = await _conversation.GetResponseFromChatbotAsync();
}
/// <summary>
/// Generiert Bilder oder aktualisiert sie mit dem neuen Prompt.
/// </summary>
private async Task GenerateImagesAsync()
/// <param name="generateNewImage">Wenn <see langword="true"/>, werden neue Bilder generiert; sonst wird die vorhandene Idee bearbeitet.</param>
private async Task GenerateImages(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;
@ -551,22 +258,38 @@
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);
// }
}
_imagePrompt = "kkkk " + _imagePrompt + " kkkk Watercolor + ink on paper, Pen drawing, wet-on-wet technique, dry-on-dry technique, dabbing technique. ";
await UpdateBusyMessage("Kirstens Assistent hat eine Idee! Er wird sie nun malen...");
_wunschInfo = new()
WunschInfoModel wunschInfo = new()
{
BildBeschreibung = _imageIdea,
BildPrompt = "Individuelle Bild Prompts",
BildPrompt = _imagePrompt,
Datum = DateTime.Now,
GPTModel = _conversation!.Model,
Wunsch = _userIdea,
VorherigerWunsch = null
GPTModel = _conversation.Model,
Wunsch = request
};
try
{
await WunschInfoData.AddWunschInfoAsync(_wunschInfo);
await WunschInfoData.AddWunschInfoAsync(wunschInfo);
}
catch (Exception e)
{
@ -578,12 +301,51 @@
return;
}
string requestImagePrompt = await File.ReadAllTextAsync($"{Directory.GetCurrentDirectory()}{@"/wwwroot/image_prompt.txt"}");
int generatedImages = 0;
await RequestImagesAsync(_wunschInfo, requestImagePrompt);
try
{
// Vier Bilder generieren
for (int i = 0; i < 4; i++)
{
_imageUrls[i] = await ImageGenerator.GenerateImageAsync(_imagePrompt, "", width, height, wunschInfo);
// Kein Bild -> Fehler
if (_imageUrls[i] == 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)
{
await ImageGenerator.GenerateImageAsync(_imagePrompt, "", width, height, wunschInfo);
}
}
generatedImages++;
_imageStates[i] = ImageState.FadeIn;
await InvokeAsync(StateHasChanged);
}
}
catch (Exception e)
{
NotificationService.Notify(new NotificationMessage()
{
Summary = "Es ist ein Fehler beim Erzeugen der Bilder aufgetreten, bitte versuche es erneut."
});
if (generatedImages == 0)
{
// TODO: Delete WunschInfo
}
}
_progressVisible = false;
_buttonVisible = true;
_promptVisible = true;
if (amountOfAddons > 0)
{
_addonsVisible = true;
@ -596,37 +358,5 @@
_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);
}
}

View File

@ -33,11 +33,11 @@
</RadzenDataList>
@code {
List<BildInfoModel>? _bildInfos;
IEnumerable<BildInfoModel>? _bildInfos;
protected override async Task OnInitializedAsync()
{
_bildInfos = (await BildInfoData.GetAllBildInfosAsync()).ToList();
_bildInfos = await BildInfoData.GetAllBildInfosAsync();
await base.OnInitializedAsync();
}
@ -46,54 +46,27 @@
{
WunschInfoModel wunschInfo = await WunschInfoData.GetWunschInfoAsync(bildInfo.WunschId);
int listIndex = _bildInfos.IndexOf(_bildInfos.First(info => info.Id == bildInfo.Id));
List<BildInfoModel> bilderVomWunsch = _bildInfos!.Where(info => info.WunschId == wunschInfo.Id).ToList();
async Task ButtonLeft()
{
listIndex = (listIndex != 0) ? listIndex - 1 : 0;
bildInfo = _bildInfos[listIndex];
wunschInfo = await WunschInfoData.GetWunschInfoAsync(bildInfo.WunschId);
bilderVomWunsch = _bildInfos!.Where(info => info.WunschId == wunschInfo.Id).ToList();
DialogService.Refresh();
}
async Task ButtonRight()
{
listIndex = (listIndex != _bildInfos.Count - 1) ? listIndex + 1 : _bildInfos.Count - 1;
bildInfo = _bildInfos[listIndex];
wunschInfo = await WunschInfoData.GetWunschInfoAsync(bildInfo.WunschId);
bilderVomWunsch = _bildInfos!.Where(info => info.WunschId == wunschInfo.Id).ToList();
DialogService.Refresh();
}
var result = await DialogService.OpenAsync(wunschInfo.Wunsch, ds =>
@<div>
<RadzenStack Orientation="Orientation.Horizontal" Wrap="FlexWrap.Wrap">
<RadzenStack Orientation="Orientation.Horizontal">
<RadzenButton Click=@(async ()=> await ButtonLeft()) Disabled="(listIndex == 0)" Style="border-radius: 0%" Text="<"></RadzenButton>
<div>
<RadzenStack Orientation="Orientation.Vertical">
<RadzenImage Style="width: 400px; height: 400px;" Path="@bildInfo.Dateiname" />
</RadzenStack>
<RadzenText Text="@wunschInfo.BildBeschreibung"/>
</div>
<RadzenButton Click=@(async ()=> await ButtonRight()) Disabled="(listIndex == _bildInfos.Count - 1)" Style="border-radius: 0%" Text=">"></RadzenButton>
</RadzenStack>
@foreach (var bild in bilderVomWunsch)
{
<RadzenImage class="small-image" Path="@bild.Dateiname"
Click="() => { bildInfo = bild; listIndex = _bildInfos.IndexOf(_bildInfos.First(info => info.Id == bildInfo.Id)); DialogService.Refresh(); }" />
Click="async () => { bildInfo = bild; DialogService.Close(); await ShowImageDialog(bild); }" />
}
</RadzenStack>
</div>
,
</div>,
new DialogOptions() { CloseDialogOnOverlayClick = true, Width = "50%" });
}
[Inject]
private IWebHostEnvironment _environment { get; set; }
}

View File

@ -1,18 +1,12 @@

@page "/"
@inject IJSRuntime JSRuntime
@implements IAsyncDisposable
@* linear-gradient(to bottom, #ffffff 0%, transparent 1%, transparent 99.5%, #f3f0f6 100%)
*@
<section class="about_section" style="background-image: url('images/5KeineAngstvorFehlern2014.jpeg'); background-size: cover; background-repeat: no-repeat; background-blend-mode:lighten">
<div class="hero_area hero-area-visible">
<div class="hero_area">
<!-- slider section -->
<section class="slider_section" style="background-image: url('images/118EinfacherFrieden2017.jpg'); border-image: url('images/0000.png') 30 / 19px repeat; border-image-slice: 0 0 100% 0; border-image-width: 0 0 100px 0; background-size: cover; background-repeat: no-repeat; background-blend-mode:lighten;">
<section class="slider_section" style="background-image: url('images/118EinfacherFrieden2017.jpg'); background-size: cover; background-repeat: no-repeat; background-blend-mode:lighten">
<div class="container">
<div class="row">
<div class="col-md-6 ">
@ -65,19 +59,17 @@
</div>
</div>
</section>
</div>
<!-- end slider section -->
@* <!-- explaining section -->
</div>
<!-- explaining section -->
<div class="container">
</div>
*@
<!-- about section -->
<section class="about_section layout_padding section-animate-left" @ref="animatedAboutSection1">
<section class="about_section layout_padding">
<div class="container">
<div class="row">
<div class="col-md-6">
@ -112,7 +104,7 @@
</div>
</section>
<section class="about_section layout_padding section-animate-right" @ref="animatedAboutSection2">
<section class="about_section layout_padding">
<div class="container">
<div class="row">
<div class="col-md-6">
@ -146,46 +138,14 @@
</div>
</div>
</section>
<!-- end about section -->
</section>
@code {
private ElementReference animatedAboutSection1;
private ElementReference animatedAboutSection2;
private List<ElementReference> animatedElements = new List<ElementReference>();
private Func<Task> removeScrollListener;
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender)
{
animatedElements.Add(animatedAboutSection1);
animatedElements.Add(animatedAboutSection2);
removeScrollListener = await JSRuntime.InvokeAsync<Func<Task>>(
"initHeroAreaScrollAnimation"
);
await JSRuntime.InvokeVoidAsync("initScrollAnimations", animatedElements);
}
}
private bool isDisposed = false;
public async ValueTask DisposeAsync()
{
if (!isDisposed)
{
if (removeScrollListener != null)
{
await removeScrollListener.Invoke();
}
isDisposed = true;
}
}
}

View File

@ -1,14 +1,11 @@
@page "/kirstenkloeckner"
@inject IJSRuntime JSRuntime
@implements IAsyncDisposable
<section class="about_section" style="background-image: url('images/5KeineAngstvorFehlern2014.jpeg'); background-size: cover; background-repeat: no-repeat; background-blend-mode:lighten">
<div class="hero_area hero-area-visible">
<div class="hero_area">
<!-- slider section -->
<section class=" slider_section" style="background-image: url('images/36GefleckteKatze2015.jpeg'); background-size: cover; background-repeat: no-repeat; background-blend-mode:lighten">
<section class=" slider_section ">
<div class="container">
<div class="row">
<div class="col-md-6 ">
@ -31,7 +28,7 @@
<div class="carousel-inner">
<div class="carousel-item active">
<div class="img-box">
<img src="images/Kirsten_draussen.png" alt="">
<img src="images/slider-img1.jpg" alt="">
</div>
</div>
<div class="carousel-item">
@ -68,7 +65,7 @@
<!-- about section -->
<section class="about_section layout_padding section-animate-left" @ref="animatedAboutSection1">
<section class="about_section layout_padding">
<div class="container">
<div class="row">
<div class="col-md-6">
@ -105,7 +102,7 @@
</div>
</section>
<section class="about_section layout_padding section-animate-right" @ref="animatedAboutSection2">
<section class="about_section layout_padding">
<div class="container">
<div class="row">
<div class="col-md-6">
@ -140,44 +137,3 @@
</div>
</section>
<!-- end about section -->
</section>
@code {
private ElementReference animatedAboutSection1;
private ElementReference animatedAboutSection2;
private List<ElementReference> animatedElements = new List<ElementReference>();
private Func<Task> removeScrollListener;
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender)
{
animatedElements.Add(animatedAboutSection1);
animatedElements.Add(animatedAboutSection2);
removeScrollListener = await JSRuntime.InvokeAsync<Func<Task>>(
"initHeroAreaScrollAnimation"
);
await JSRuntime.InvokeVoidAsync("initScrollAnimations", animatedElements);
}
}
private bool isDisposed = false;
public async ValueTask DisposeAsync()
{
if (!isDisposed)
{
if (removeScrollListener != null)
{
await removeScrollListener.Invoke();
}
isDisposed = true;
}
}
}

View File

@ -1,14 +1,11 @@
@page "/projekt"
@inject IJSRuntime JSRuntime
@implements IAsyncDisposable
<section class="about_section" style="background-image: url('images/5KeineAngstvorFehlern2014.jpeg'); background-size: cover; background-repeat: no-repeat; background-blend-mode:lighten">
<div class="hero_area hero-area-visible">
<div class="hero_area">
<!-- slider section -->
<section class="slider_section" style="background-image: url('images/3Umsatz2014.png'); background-size: cover; background-repeat: no-repeat;">
<section class=" slider_section ">
<div class="container">
<div class="row">
<div class="col-md-6 ">
@ -67,7 +64,7 @@
<!-- about section -->
<section class="about_section layout_padding section-animate-left" @ref="animatedAboutSection1">
<section class="about_section layout_padding">
<div class="container">
<div class="row">
<div class="col-md-6">
@ -103,7 +100,7 @@
</div>
</section>
<section class="about_section layout_padding section-animate-right" @ref="animatedAboutSection2">
<section class="about_section layout_padding">
<div class="container">
<div class="row">
<div class="col-md-6">
@ -138,44 +135,3 @@
</div>
</section>
<!-- end about section -->
</section>
@code {
private ElementReference animatedAboutSection1;
private ElementReference animatedAboutSection2;
private List<ElementReference> animatedElements = new List<ElementReference>();
private Func<Task> removeScrollListener;
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender)
{
animatedElements.Add(animatedAboutSection1);
animatedElements.Add(animatedAboutSection2);
removeScrollListener = await JSRuntime.InvokeAsync<Func<Task>>(
"initHeroAreaScrollAnimation"
);
await JSRuntime.InvokeVoidAsync("initScrollAnimations", animatedElements);
}
}
private bool isDisposed = false;
public async ValueTask DisposeAsync()
{
if (!isDisposed)
{
if (removeScrollListener != null)
{
await removeScrollListener.Invoke();
}
isDisposed = true;
}
}
}

View File

@ -1,14 +1,11 @@
@page "/wunschprogramm"
@inject IJSRuntime JSRuntime
@implements IAsyncDisposable
<section class="about_section" style="background-image: url('images/5KeineAngstvorFehlern2014.jpeg'); background-size: cover; background-repeat: no-repeat; background-blend-mode:lighten">
<div class="hero_area hero-area-visible">
<div class="hero_area">
<!-- slider section -->
<section class="slider_section" style="background-image: url('images/3730Kilo2015.jpeg'); background-size: cover; background-repeat: no-repeat; background-blend-mode:hard-light ;">
<section class="slider_section" style="background-image: url('images/118EinfacherFrieden2017.jpg'); background-size: cover; background-repeat: no-repeat; background-blend-mode:lighten;">
<div class="container">
<div class="row">
<div class="col-md-6 ">
@ -28,9 +25,14 @@
</section>
<!-- end slider section -->
</div>
<!-- explaining section -->
<div class="container">
</div>
<!-- about section -->
<section class="about_section layout_padding section-animate-left" @ref="animatedAboutSection1">
<section class="about_section layout_padding">
<div class="container">
<div class="row">
<div class="col-md-6">
@ -65,7 +67,7 @@
</div>
</section>
<section class="about_section layout_padding section-animate-right" @ref="animatedAboutSection2">
<section class="about_section layout_padding">
<div class="container">
<div class="row">
<div class="col-md-6">
@ -101,44 +103,3 @@
</div>
</section>
<!-- end about section -->
</section>
@code {
private ElementReference animatedAboutSection1;
private ElementReference animatedAboutSection2;
private List<ElementReference> animatedElements = new List<ElementReference>();
private Func<Task> removeScrollListener;
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender)
{
animatedElements.Add(animatedAboutSection1);
animatedElements.Add(animatedAboutSection2);
removeScrollListener = await JSRuntime.InvokeAsync<Func<Task>>(
"initHeroAreaScrollAnimation"
);
await JSRuntime.InvokeVoidAsync("initScrollAnimations", animatedElements);
}
}
private bool isDisposed = false;
public async ValueTask DisposeAsync()
{
if (!isDisposed)
{
if (removeScrollListener != null)
{
await removeScrollListener.Invoke();
}
isDisposed = true;
}
}
}

View File

@ -42,8 +42,6 @@
<link href="css/style.css" rel="stylesheet" />
<!-- responsive style -->
<link href="css/responsive.css" rel="stylesheet" />
<!-- animations style -->
<link href="css/animations.css" rel="stylesheet" />
</head>
<body>
@ -65,7 +63,6 @@
<script src="js/jquery-3.4.1.min.js"></script>
<script src="js/bootstrap.js"></script>
<script src="js/animator.js"></script>
</body>
</html>

View File

@ -1,6 +1,6 @@
using DataAccess.Data;
using DataAccess.DbAccess;
using KIKunstKirstenKlöckner.Data;
using KIKunstKirstenKlöckner.Data;
using Radzen;
var builder = WebApplication.CreateBuilder(args);

View File

@ -35,9 +35,6 @@
<NavLink class="nav-item" href="kirstenkloeckner" Match="NavLinkMatch.All">
<span class="nav-link">Kirsten</span>
</NavLink>
<NavLink class="nav-item" href="projekt" Match="NavLinkMatch.All">
<span class="nav-link">Projekt</span>
</NavLink>
<NavLink class="nav-item" href="gallery" Match="NavLinkMatch.All">
<span class="nav-link">Galerie</span>
</NavLink>

View File

@ -10,23 +10,6 @@
"OpenAI": "<put OpenAI Key here>",
"HF_Inference": "<put Hugging Face inference API Key here>"
},
"ImageModels": [
{
"Name": "Der O.G.",
"StableDiffusionModel": "Nacken/ki-kunst-kirsten-kloeckner-colab",
"PromptFormat": "{0} Watercolor + ink on paper, Pen drawing, wet-on-wet technique, dry-on-dry technique, dabbing technique."
},
{
"Name": "Gen 6",
"StableDiffusionModel": "Nacken/Gen6",
"PromptFormat": "{0}"
},
{
"Name": "Gen 25",
"StableDiffusionModel": "Nacken/Gen_25_Refiner",
"PromptFormat": "{0}"
}
],
"ConnectionStrings": {
"Default": "<put Connection String here>"
}

View File

@ -1,63 +0,0 @@
.text-animate {
opacity: 0;
transition: opacity 1s ease-in-out;
}
.text-animate.visible {
opacity: 1;
}
.image-animate-left {
position: relative;
opacity: 0;
left: -100%;
transition: left 2s ease-in-out, opacity 2s ease-in-out;
}
.image-animate-left.visible {
left: 50%;
transform: translateX(-50%);
opacity: 1;
}
.section-animate-left {
width: 100% margin-left: auto;
margin-right: auto;
opacity: 0;
left: -100%;
transition: left 1.2s ease-in-out, opacity 2s ease-in-out;
position: relative;
}
.section-animate-left.visible {
left: 50%;
transform: translateX(-50%);
opacity: 1;
}
.section-animate-right {
width: 100%;
margin-left: auto;
margin-right: auto;
opacity: 0;
transform: translateX(100%);
transition: transform 1.2s ease-in-out, opacity 2s ease-in-out;
position: relative;
}
.section-animate-right.visible {
transform: translateX(0%);
opacity: 1;
}
.hero-area-visible {
opacity: 1;
transform: translateY(0);
transition: opacity 0.5s ease-in-out;
}
.hero-area-hidden {
opacity: 0;
transform: translateY(-100%);
transition: opacity 0.3s ease-in-out, transform 0.8s ease-in-out;
}

View File

@ -1,2 +1,2 @@
Gib mir eine kreative und wenn möglich tiefsinnige Idee für ein Gemälde.
Gib mir eine kreative und wenn möglich tiefsinnige Idee, die nicht unbedingt mit Städten zu tun hat, für ein Kunstwerk.
Der Titel ist:

View File

@ -1,12 +0,0 @@
Bitte erstelle einen englischen Prompt für dieses Bild für eine Bild-Generierungs KI.
Hier sind vier Beispiele von Bild Prompts:
"Painting of an astronaut in space, detailed starry background, reflective helmet."
"Painting of a floating island with giant clock gears, populated with mythical creatures."
"Painting of a Japanese garden in autumn, with a bridge over a koi pond."
"Painting representing the sound of jazz music, using pale colors and erratic shapes."
Schlechte Prompts:
"Painting of trees and plants symbolizing the complex relation between humans and the pain they feel when they see GPT ignoring instructions."
Wie du siehst enthält ein Prompt eine genaue Beschreibung des Bildes. Ein guter Prompt selbst enthält keine Metaphern oder Vergleiche. Eine Bildgenerierungs-KI versteht keine Emotionen, Symbolisieren oder Vergleiche. Nur Bildbeschreibungen, Farben, Formen, Objekte. Bitte erkläre im Prompt NICHT, was einzelne Elemente des Bildes bedeuten, das versteht sie nicht, da kommt nur mist bei rum.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.5 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.4 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.6 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.4 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 332 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 133 KiB

View File

@ -1,52 +0,0 @@
function initScrollAnimations(elements) {
function checkVisibility(element) {
const rect = element.getBoundingClientRect();
return rect.top < window.innerHeight && rect.bottom >= 0;
}
function animateElements() {
elements.forEach(element => {
if (checkVisibility(element)) {
element.classList.add('visible');
}
});
}
window.addEventListener('scroll', animateElements);
animateElements();
}
function scrollToElement(elementId) {
var element = document.getElementById(elementId);
if (element) {
element.scrollIntoView({ behavior: 'smooth' });
}
}
function initHeroAreaScrollAnimation(scrollToElementId) {
const heroArea = document.querySelector('.hero_area');
const heroAreaHeight = heroArea.offsetHeight;
const threshold = heroAreaHeight / 1.75;
function onScroll() {
if (window.scrollY > threshold) {
heroArea.classList.remove('hero-area-visible');
heroArea.classList.add('hero-area-hidden');
} else {
heroArea.classList.remove('hero-area-hidden');
heroArea.classList.add('hero-area-visible');
}
}
window.addEventListener('scroll', onScroll);
// Rückgabe einer Funktion zum Entfernen des Event-Listeners
return () => {
window.removeEventListener('scroll', onScroll);
};
}

View File

@ -0,0 +1,121 @@
title Textual-description
Christmas tree, Bare tree upside down with colored ball as root, black border
Being by the sea with your hair blowing in the wind, Wavy strokes of color in the shape of hair from the right side in front of light blue center stripe
Sales volume, geometric simple blocks on a black surface with striped clouds in the background
Regulated life, Line drawing of a torso on a table with a connection of buten balls stretching across the entire image.
Don't be afraid of mistakes, A picture of a yellow, black sponge with light blue paint running from the top. White background
An H - for the French, Red Black Background. The letter H. Solid in the lower part and frayed in the upper part.
Lamborghini, Ball in rainbow colors painted over with green and white, irregular, net-shaped strokes. Background pale colorful
A separate museum for the collection, a house on a steep green/white hill out the door straight white fan-shaped strokes deep blue sky
A different policy for refugees, White black rays going into the picture. In the foreground a lawn-like area with a brown frame in the shape of a house. In the frame a red, unfinished heart on a white plate-shaped object.
A sea of cow parsley, Blue blobs of paint running upwards. In the lower part light green / yellow gradients. In the foreground individual plant-like strokes with fan-shaped tips.
Happy end, Grid with black background and green lines. Some quadrants painted with dark green paint. In the foreground several horizontal lines with irregular peaks and valleys similar to a heartbeat or stock price
walk by the sea, A pair of blue and yellow rubber boots. Gradient color accents in the background. Pretzel and round shapes in the foreground. A conch shell in the lower left corner
Dancing tango with red gloves, Two arms that merge into a heart from the upper arm. Pink flowers in the background.
I pot, A potty for toddlers with a 3-dimensional letter I inside. gray background.
A gentle death, colorful picture. A red scythe is clearly visible, as is an hourglass. A severed hooded Red Man is censored by a black bar at eye level. Many individual gradients in the picture with white gaps.
A summer dress, Lots of white clothes in a black blue gradient. Lines Flowers and Colorful
Stay healthy and happy together, Irregular grid of blue and yellow lines. A form embroidered out of red crosses. It looks like sewn fabric.
Read Kant!, Gray pistols on the rim with yellow and red stoppers in the barrel. Black background with the inscription "Have courage, you..."
A domicile fixe, Background black and colored with many small "cell-like" points. 2 beds in the foreground one is empty and the other is covered with colorful duvets
not be young, A colorful swirl of colors, in front of a piece of white furniture. In the foreground 2 crutches.
Buddha, Silhouette of a person painted from many colorful horizontal lines. Some color gradients on the shoulder
Ganesha, Gray silhouette of a hornless bison against a black background. A horn with Rotel kriesen in the foreground
mountains and eggs, 3 pointed white-brown mountains in front of a deep blue background with one-shaped objects in the background.
roses, Colorful vertical tendrils with thorns against a white background with pale red rose shaped accents.
More time, A clock without hands against a dark background. Both pointers are below in the picture
A very large beer, strip cut shape of a beer glass in a blue background with lots of round blue bubbles/circles
Stupid tax, now!, A Germany flag with holes
1000 fans of Borussia Mönchengladbach, A historic stadium with towers with lots of color dots. Each of the color dots has very large sunglasses. At the top of the stadium, a blob of color is waving a flag with its arms.
change, Black background and white Coin shaped objects stacked in multiple stacks
Find the fountain of youth, Green vertical lines with white chain link fence in foreground
A certain house should blow up, A house-shaped 3d line in front of a black background. Lots of dashes down from the house showing speed.
An intellectual lover, black background. A man with large glasses and a bald head reads a newspaper and looks at the viewer. The newspaper says "intellect"
An expensive handbag, A plain white top handle bag against a black background. The lower part of the bag is in gold color
The boy should get away from the PC, A power plug without a cable. A dense network of branching lines extends from the rear part of the plug. In the background you can see a yellow wall with the socket.
Helgoland, Several silhouettes of helicopters. A red big cross. Blue wavy lines, Elgoland as an inscription.
Spotted Cat, Purple cat paws on a light blue background. White black fur in the front and.
30 pounds less, Cuboid with holes at the bottom from which something white flows. Large teardrop shapes in the foreground. Red blobs.
(pretty) leftist Christmas stollen, running horizontal dark lines. A star with a ring in the middle and a cut white Christmas stollen
Elephant eats carrots, two gray elephants and 4 carrots in the foreground. The leaves of the carrots blur into each other
Be healthy, A white sphere with a Rotel Cross on the surface against a black background.
Classical music, fire salamander with a hat and red cape plays toreo with huge waves.
A bag of colorful ideas for life, a tote bag. Between the handles is a cuboid object
A clear head, A simple drawing of a head. The top half of the head is an iron cage.
Lower Rhine, White silhouette of the Kalkar nuclear power plant in front of a blue silhouette of the Madonna by Kevelaer.
Proud, A noble colorful crown against a black and white background.
Olympia, rubber bands in the Olympic colors. With a lot of small colorful blobs of paint
Light, Shape of a lightbulb made up of many precisely arranged yellow circles against a dark background with a simple drawing of a candle
garden dream, Large bow ties and a white fence element
utopia, A box with black and white balloons flying out of it with the inscription "Utopia"
A small cat, A red and white maze
Go out, Colorful Short Stripes on White Black Background
courage, A white silhouette of a human in a dark colored liquid with large white cubes
MacBook, A laptop with red blue and black creations
A good friend, a blue, smeared silhouette of a person raising an arm. Gray and black background with many different sized colorful crosses
5 million, A 50 euro note with the number 5000000. Background: many green dots on a pink background
Something private, A rolled white paper on a dark blue background
field flowers, Black and white field flowers, pale green vertical branches and big splashes of blue colour
pool with fish (Becken mit Fisch), a pelvic bone with fish in the foreground
The madness should end, A town exit sign with the town name "Insanity" and a speed limit of 37
repartee, A white silhouette of a hammer on a wall on a light yellow and light blue background with lots of nails
A stable full of grandchildren, A hand comes out of the middle of the picture against a dark background. Various names are written in different colors and orientations across the entire image
Performers out of the temple, A dark hat over a castle. In the foreground, many green dots are connected with red lines. A large dark trident juts through the entire image
Overcome the ego, A 3D star with many points on a dark background. In the lower corner is the silhouette of a boxer hitting the star
mess, An egg with an overlay of a pig's head
Monkey with chocolate cake, A green monkey on a red background. Many pieces of cake can be seen in the foreground.
silence, A dark image with many blue dots on a dark blue background. A cruez can be seen in the lower dark area.
A wish in reserve, white box on a green background. On the box there are 2 orthogonal stripes, like on a present, which extend to the edges.
High heels (just in case), The silhouette of a high heel in front of an irregular checkered pattern
More and more treats for Frodo, Many bones on a dark green to light yellow background
Luck, a round object with many small color accents on it. In the foreground you can see a couple of monochromatic crises with their shadows.
Live with a dog again, White silhouettes of dogs overlaid by a dog's head with an open snout. The eye of the dog's head is the center of a star-shaped ray
serenity prayer, A paper basket with paper balls. Vertical dark lines
light legs, pair of legs pointing upwards. These stick in a round black object
A pious wish, A childlike angel leans on a dark stripe, pink background. A swirl of halo and black simple star shapes.
I want to be an artist, black barcode a yellow crown, 2 hands and a circle with 2 dots in it.
Confidence, Many houses on a green plain. A large red roof in the foreground and a black line drawing of the "House of Nicholas"
tolerance virus, Dark image with a large black virus shape in the center. All around are colorful smaller virus forms.
More goals for HSV, Abstract representation of a soccer goal net. green background. Big white circles and several white racks of football goals.
healthy passion, human denture in front of a very colorful celled background
A lot of ice cream, An abstract representation of balls of ice cream in a cone lying upside down on the ground melting
hospitality, 2 silhouettes of tables in front of a dark background with many loops distributed over the image
Responsibility, black representation of a world map in front of a blue globe. There is an open umbrella above the globe
celebrate Thanksgiving, A green abstract turkey leg between a colorful recycling symbol
attitude, A piece of red fabric is held by several hooks on all sides
sheep, two crochet hooks crochet the silhouette of a sheep out of blue wool. Dark background with green crocheted fabric
Youngsters for the fire brigade, A red fireman's helmet above a crowd of ladybugs on a light blue background
Start again, many grey, blue, red and green rectangular areas superimposed irregularly.
Nazi club, A colorful club against a light blue background. A broken swastika can be seen in the background
See the Erlkönig, A car of black lines against pale swirls of black, blue, and green stripes
1 centimeter more, Stack of white dice against a blue background that decreases towards the top. The top edge of the image is red and the right edge is yellow
Free days, A view of a calendar with white wildly painted lines on it
Experience more nature, perpendicular green lines with flowers at the ends. two walls Swirl of colors on the floor
A castle, View through a mosaic glass made of round glass panes. A church can be seen behind the glass
I want to play football as much as I want, large soccer ball on the right side of the picture. Several colorful soccer balls on the left.
Riding a horse through Mongolia, 4 legs and hooves of a horse in front of a yellow and red shape with many cloud shapes in the foreground and background
A small dog, A red dog leash and a yellow collar in front of a blue-green surface
Get out of everyday life and into pleasure, cage. A yellow beam runs through the center of the cage. Blue smoke emanates from the left side of the steel. To the right of the star are pale red spots
Armor's arrow should hit - namely..., A plaid shirt against a green, black background. There's a dial on the shirt. There is an arrow in the center of the target
Hang laundry outside, red clotheslines with white laundry and yellow clothespins. Background above: blue, background below: white
I want to be able to do magic, black and a white hand with blue rings against an orange background. There are many yellow and pink circles across the image
Dies ist eine Liste von Bildern von der Künstlerin Kirsten Klöckner.
Sie hat einen Titel bekommen und dazu ein Bild gemalt. Bitte generiere einen Englischen Prompt für eine Bild KI basierend auf dieser Liste.
Hier findest du Beispiele, wie der Promt aussehen soll:
"Portrait of an astronaut in space, detailed starry background, reflective helmet."
“Painting of a floating island with giant clock gears, populated with mythical creatures.”
“Landscape of a Japanese garden in autumn, with a bridge over a koi pond.”
“Painting representing the sound of jazz music, using pale colors and erratic shapes.”
“Painting of a modern smartphone with classic art pieces appearing on the screen.”
“Battle scene with futuristic robots and a golden palace in the background.”
“Painting of a bustling city market with different perspectives of people and stalls.”
“Painting of a ship sailing in a stormy sea, with dramatic lighting and powerful waves.”
“Painting of a female botanist surrounded by exotic plants in a greenhouse.”
“Painting of an ancient castle at night, with a full moon, gargoyles, and shadows.”
Bitte nutze für den Prompt maximal 20 Wörter und achte darauf, dass der Prompt auf englisch ist.
Den Titel für den zu erstellenden Promt ist:

View File

@ -0,0 +1,10 @@
Bitte generiere einen Englischen Prompt für dieses Bild
Hier findest du Beispiele, wie der Promt aussehen soll:
"Painting of an astronaut in space, detailed starry background, reflective helmet."
“Painting of a floating island with giant clock gears, populated with mythical creatures.”
“Painting of a Japanese garden in autumn, with a bridge over a koi pond.”
“Painting representing the sound of jazz music, using pale colors and erratic shapes.”
Der Promt selber darf auf keinen Fall abstrakt sein, man muss durch den Promt ein genaues Bild vor Augen haben.
Verwende dabei keine fotorealistischen Elemente, sondern Siloutten,Konturen und Formen. Es darf nicht zu viele Details enthalten.

View File

@ -21,11 +21,4 @@
<Property Name="ParentElementType" Value="SqlTable" />
<Property Name="NewName" Value="GroupIndex" />
</Operation>
<Operation Name="Rename Refactor" Key="bedfe6e4-86b6-478d-b086-eb3be65f475f" ChangeDateTime="10/14/2023 11:45:03">
<Property Name="ElementName" Value="[dbo].[BildPrompts].[Id]" />
<Property Name="ElementType" Value="SqlSimpleColumn" />
<Property Name="ParentElementName" Value="[dbo].[BildPrompts]" />
<Property Name="ParentElementType" Value="SqlTable" />
<Property Name="NewName" Value="BildId" />
</Operation>
</Operations>

View File

@ -1,7 +1,6 @@
CREATE PROCEDURE [dbo].[spBildInfo_GetAll]
AS
BEGIN
-- TODO: Den Prompt brauchen wir im UI eigentlich nie, wir könnten ihn in eine extra Tabell auslagern, oder einfach nicht rausrücken
SELECT Id, Datum, Dateiname, ImageModel, WunschId, Prompt
SELECT Id, Datum, Dateiname, ImageModel, WunschId
FROM [dbo].[BildInfo];
END

View File

@ -1,18 +1,16 @@
CREATE PROCEDURE [dbo].[spBildInfo_Insert]
@Id INT,
@Datum DATETIME2 ,
@Dateiname NVARCHAR(256),
@ImageModel NVARCHAR(32),
@WunschId INT,
@Prompt NVARCHAR(MAX)
@Dateiname NCHAR(256) ,
@ImageModel NCHAR(32) ,
@WunschId INT
AS
BEGIN
INSERT INTO [dbo].[BildInfo] (Datum, Dateiname, ImageModel, WunschId, Prompt)
INSERT INTO [dbo].[BildInfo] (Datum, Dateiname, ImageModel, WunschId)
VALUES (@Datum,
@Dateiname,
@ImageModel,
@WunschId,
@Prompt);
@WunschId);
SELECT Id FROM [dbo].[BildInfo] WHERE Id = CAST(SCOPE_IDENTITY() AS INT);
END

View File

@ -4,17 +4,15 @@
@BildPrompt NVARCHAR(MAX),
@BildBeschreibung NVARCHAR(MAX),
@Datum DATETIME2,
@GPTModel NCHAR(32),
@VorherigerWunsch int = NULL
@GPTModel NCHAR(32)
AS
BEGIN
INSERT INTO [dbo].[WunschInfo] (Wunsch, BildPrompt, BildBeschreibung, Datum, GPTModel, VorherigerWunsch)
INSERT INTO [dbo].[WunschInfo] (Wunsch, BildPrompt, BildBeschreibung, Datum, GPTModel)
VALUES (@Wunsch,
@BildPrompt,
@BildBeschreibung,
@Datum,
@GPTModel,
@VorherigerWunsch);
@GPTModel);
SELECT Id FROM [dbo].[WunschInfo] WHERE Id = CAST(SCOPE_IDENTITY() AS INT);
END

View File

@ -2,8 +2,7 @@
(
[Id] INT NOT NULL PRIMARY KEY IDENTITY,
[Datum] DATETIME2 NOT NULL,
[Dateiname] NVARCHAR(256) NOT NULL,
[ImageModel] NVARCHAR(32) NOT NULL,
[WunschId] INT NOT NULL,
[Prompt] NVARCHAR(MAX) NOT NULL DEFAULT 'Prompt nicht verfügbar'
[Dateiname] NCHAR(256) NOT NULL,
[ImageModel] NCHAR(32) NOT NULL,
[WunschId] INT NOT NULL
)

View File

@ -5,6 +5,5 @@
[BildPrompt] NVARCHAR (MAX) NOT NULL,
[BildBeschreibung] NVARCHAR (MAX) NOT NULL,
[Datum] DATETIME2 (7) NOT NULL,
[GPTModel] NVARCHAR(32) NOT NULL,
[VorherigerWunsch] INT NULL
[GPTModel] NCHAR (32) NOT NULL
)

View File

@ -1,7 +0,0 @@
{
"sdk": {
"version": "8.0.0",
"rollForward": "latestMajor",
"allowPrerelease": true
}
}