Compare commits

16 Commits

Author SHA1 Message Date
2d21bd86c2 Upgrade auf DotNet 8.0 und C# 12 2024-06-30 14:28:44 +02:00
76bb1fa40f Update Dependencies, add GPT4o 2024-06-30 14:16:16 +02:00
0f738b2264 Small fixes + use utf-8 in projects 2024-06-30 13:38:37 +02:00
134d9399f7 Böser Bösewicht 2023-11-21 15:50:14 +01:00
4bf485d523 RIPPchen fertich 2023-11-17 15:14:43 +01:00
ddc65799f5 GRADIENT! 2023-11-17 14:28:22 +01:00
3406748c66 Karusell auf ai art seite gefixrt 2023-11-17 13:33:05 +01:00
d8726fbc59 noch mehr tolle sachen. TODO Das runde ding rechts funktioniert noch nicht wie es soll. 2023-11-17 01:35:14 +01:00
8504d79a3d Noch mehr super tolle Animationen die überhaupt gar kein Krebs waren zu implementieren und super toll aussehen und gar kein krebs waren zu implementieren :D 2023-11-17 00:34:22 +01:00
98810ad1fc Merge branch 'main' of https://gitfrieds.nackenbox.xyz/Gottfried/KI-Kunst-Kirsten-Kloeckner 2023-11-16 23:00:14 +01:00
3fb4ab3934 Gallery fixed 2023-11-16 23:00:04 +01:00
74fe4ca4a1 Fancy animation zur image section wenn generate butten gepresst wurde. 2023-11-16 22:47:03 +01:00
a4e6cc4518 Animationen sind ganz toll und gar kein krampf :D 2023-11-16 22:05:00 +01:00
5d8d3f1f2f Buttons zum Bilder switchen und Dialog.refresh 2023-11-13 14:59:10 +01:00
538445760e GPT4 Turbo 2023-11-10 13:57:21 +01:00
18e9d7ef5d Bildmodell SDXL 18000 weg, Gen 25 rein 2023-10-27 11:15:03 +02:00
34 changed files with 1238 additions and 534 deletions

4
.editorconfig Normal file
View File

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

13
.idea/.idea.KIKunstKirstenKlöckner/.idea/.gitignore generated vendored Normal file
View File

@ -0,0 +1,13 @@
# 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

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

View File

@ -0,0 +1,19 @@
<?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

@ -0,0 +1,6 @@
<?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

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

View File

@ -0,0 +1,38 @@
<?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

@ -0,0 +1,12 @@
<?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

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

View File

@ -1,15 +1,16 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<LangVersion>12</LangVersion>
</PropertyGroup>
<ItemGroup>
<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" />
<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" />
</ItemGroup>
</Project>

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("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DataAccess", "DataAccess\DataAccess.csproj", "{0880FD07-236B-42C1-9CA3-2A6F695A623C}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DataAccess", "DataAccess\DataAccess.csproj", "{0880FD07-236B-42C1-9CA3-2A6F695A623C}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution

View File

@ -1,4 +1,14 @@
<Router AppAssembly="@typeof(App).Assembly">
@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">
<Found Context="routeData">
<RouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)" />
<FocusOnNavigate RouteData="@routeData" Selector="h1" />
@ -6,7 +16,54 @@
<NotFound>
<PageTitle>Not found</PageTitle>
<LayoutView Layout="@typeof(MainLayout)">
<p role="alert">Sorry, there's nothing at this address.</p>
<p style="text-align:center;" role="alert">@_text</p>
@* @_mus *@
</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,6 +1,9 @@
namespace KIKunstKirstenKlöckner.Data;
using OpenAI_API.Models;
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;

View File

@ -0,0 +1,23 @@
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,22 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<TargetFramework>net8.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.18.1" />
<PackageReference Include="OpenAI" Version="1.7.2" />
<PackageReference Include="Radzen.Blazor" Version="4.14.4" />
<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" />
</ItemGroup>
<ItemGroup>
<Folder Include="wwwroot\NewFolder\" />
<PackageReference Include="SixLabors.ImageSharp" Version="3.0.1" />
<PackageReference Include="SixLabors.ImageSharp" Version="3.1.4" />
</ItemGroup>
<ItemGroup>

View File

@ -6,19 +6,111 @@
@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 WunschInfoData WunschInfoData;
@inject ImageGenerator ImageGenerator;
@inject BildInfoData BildInfoData;
@inject WunschInfoData WunschInfoData;
<PageTitle>AiArt</PageTitle>
@implements IAsyncDisposable
<section class="about_section layout_padding" style="background-image: url('images/5KeineAngstvorFehlern2014.jpeg'); background-size: cover; background-repeat: no-repeat; background-blend-mode:lighten">
<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">
<div class="container">
<RadzenStack Orientation="Orientation.Vertical" AlignItems="AlignItems.Center">
@ -49,23 +141,47 @@
<RadzenNumeric ShowUpDown = "false" TValue = "int?" @bind-Value=@_imageHeight />
</RadzenStack>
</RadzenStack>
<RadzenStack Orientation="Orientation.Horizontal"
AlignItems="AlignItems.Center" Wrap="FlexWrap.Wrap">
<RadzenCheckBox @bind-Value=@_useGpt4 Name="UseGPT4"/>
<RadzenLabel Text="Verwende GPT 4" Component="UseGPT4" Style="margin-left: 8px; vertical-align: middle;" />
</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"/>
<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>
</RadzenCard>
</ChildContent>
</RadzenPanel>
<RadzenButton Visible=@_buttonVisible Click=@(async ()=> await GenerateImagesAsync())>Generate</RadzenButton>
<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>
<RadzenCard class="rz-mt-4" Style="width: 800px;">
@ -89,7 +205,7 @@
Click="() => ShowImageDialog(_imageUrls[0])" />
<RadzenPanel AllowCollapse="true" Collapsed="true" Text="Info">
@_imagePromts[0]
<br/>
<br />
Model: @_bildInfos[0]?.ImageModel
</RadzenPanel>
</RadzenColumn>
@ -119,22 +235,83 @@
Click="() => ShowImageDialog(_imageUrls[3])" />
<RadzenPanel AllowCollapse="true" Collapsed="true" Text="Info">
@_imagePromts[3]
<br/>
<br />
Model: @_bildInfos[3]?.ImageModel
</RadzenPanel>
</RadzenColumn>
</RadzenRow>
</RadzenCard>
</RadzenStack>
</div>
</section>
}
@if (!_imageSectionVisible)
{
<div class="invisible-rectangle"></div>
}
</div>
</section>
<!-- end image section -->
</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>
/// Wenn <see langword="true"/> wird GPT4 verwendet um die Idee zu interpretieren.
/// Das ChatGPT Model, das zur Erzeugung der Idee und Bild-Promts verwendet wird.
/// </summary>
private bool _useGpt4;
private GptModel _usedGptModel = GptModel.Gpt3_5_turbo;
private int maxAddons = 2;
private int amountOfAddons = 0; // wird später geändert
@ -142,6 +319,7 @@
private bool _buttonVisible = true;
private bool _addonsVisible = false;
private bool _bothVisible = false;
private bool _imageSectionVisible = false;
public string BusyMessage { get; set; } = "Initial Message";
@ -173,6 +351,11 @@
,
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 float _temperature = 0.9f;
@ -211,6 +394,9 @@
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);
@ -247,7 +433,13 @@
ChatRequest chatRequest = new ChatRequest
{
Temperature = _temperature,
Model = _useGpt4 ? Model.GPT4 : Model.ChatGPTTurbo
Model = _usedGptModel switch
{
GptModel.Gpt3_5_turbo => Model.ChatGPTTurbo,
GptModel.Gpt4_turbo => ChatGPT.GPT4Turbo,
GptModel.Gpt4o => ChatGPT.GPT4o,
_ => throw new ArgumentOutOfRangeException()
}
};
_conversation = _openAiApi.Chat.CreateConversation(chatRequest);
@ -256,7 +448,6 @@
_conversation.AppendUserInput(ideaBasePrompt + " " + _userIdea);
_imageIdea = await _conversation.GetResponseFromChatbotAsync();
}
/// <summary>
/// Fordert für mehrere Bilder Bild-Prompts an und generiert die dazugehörigen Bilder.
/// </summary>

View File

@ -33,11 +33,11 @@
</RadzenDataList>
@code {
IEnumerable<BildInfoModel>? _bildInfos;
List<BildInfoModel>? _bildInfos;
protected override async Task OnInitializedAsync()
{
_bildInfos = await BildInfoData.GetAllBildInfosAsync();
_bildInfos = (await BildInfoData.GetAllBildInfosAsync()).ToList();
await base.OnInitializedAsync();
}
@ -46,27 +46,54 @@
{
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"/>
<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="async () => { bildInfo = bild; DialogService.Close(); await ShowImageDialog(bild); }" />
Click="() => { bildInfo = bild; listIndex = _bildInfos.IndexOf(_bildInfos.First(info => info.Id == bildInfo.Id)); DialogService.Refresh(); }" />
}
</RadzenStack>
</div>,
</div>
,
new DialogOptions() { CloseDialogOnOverlayClick = true, Width = "50%" });
}
[Inject]
private IWebHostEnvironment _environment { get; set; }
}

View File

@ -1,12 +1,18 @@

@page "/"
@inject IJSRuntime JSRuntime
@implements IAsyncDisposable
@* linear-gradient(to bottom, #ffffff 0%, transparent 1%, transparent 99.5%, #f3f0f6 100%)
*@
<div class="hero_area">
<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/118EinfacherFrieden2017.jpg'); background-size: cover; background-repeat: no-repeat; background-blend-mode:lighten">
<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;">
<div class="container">
<div class="row">
<div class="col-md-6 ">
@ -59,17 +65,19 @@
</div>
</div>
</section>
<!-- end slider section -->
</div>
<!-- explaining section -->
<!-- end slider section -->
@* <!-- explaining section -->
<div class="container">
</div>
*@
<!-- about section -->
<section class="about_section layout_padding">
<section class="about_section layout_padding section-animate-left" @ref="animatedAboutSection1">
<div class="container">
<div class="row">
<div class="col-md-6">
@ -104,7 +112,7 @@
</div>
</section>
<section class="about_section layout_padding">
<section class="about_section layout_padding section-animate-right" @ref="animatedAboutSection2">
<div class="container">
<div class="row">
<div class="col-md-6">
@ -138,14 +146,46 @@
</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,8 +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">
<div class="hero_area hero-area-visible">
<!-- slider section -->
<section class=" slider_section" style="background-image: url('images/36GefleckteKatze2015.jpeg'); background-size: cover; background-repeat: no-repeat; background-blend-mode:lighten">
@ -57,15 +60,15 @@
</div>
</section>
<!-- end slider section -->
</div>
<!-- explaining section -->
<div class="container">
</div>
</div>
<!-- explaining section -->
<div class="container">
</div>
<!-- about section -->
<section class="about_section layout_padding">
<!-- about section -->
<section class="about_section layout_padding section-animate-left" @ref="animatedAboutSection1">
<div class="container">
<div class="row">
<div class="col-md-6">
@ -100,9 +103,9 @@
</div>
</div>
</section>
</section>
<section class="about_section layout_padding">
<section class="about_section layout_padding section-animate-right" @ref="animatedAboutSection2">
<div class="container">
<div class="row">
<div class="col-md-6">
@ -135,5 +138,46 @@
</div>
</div>
</section>
<!-- end about section -->
</section>
<!-- end about 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,11 +1,14 @@
@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">
<div class="hero_area hero-area-visible">
<!-- slider section -->
<section class=" slider_section ">
<section class="slider_section" style="background-image: url('images/3Umsatz2014.png'); background-size: cover; background-repeat: no-repeat;">
<div class="container">
<div class="row">
<div class="col-md-6 ">
@ -56,15 +59,15 @@
</div>
</section>
<!-- end slider section -->
</div>
<!-- explaining section -->
<div class="container">
</div>
</div>
<!-- explaining section -->
<div class="container">
</div>
<!-- about section -->
<section class="about_section layout_padding">
<!-- about section -->
<section class="about_section layout_padding section-animate-left" @ref="animatedAboutSection1">
<div class="container">
<div class="row">
<div class="col-md-6">
@ -98,9 +101,9 @@
</div>
</div>
</section>
</section>
<section class="about_section layout_padding">
<section class="about_section layout_padding section-animate-right" @ref="animatedAboutSection2">
<div class="container">
<div class="row">
<div class="col-md-6">
@ -133,5 +136,46 @@
</div>
</div>
</section>
</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,8 +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">
<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:hard-light ;">
@ -24,15 +27,10 @@
</div>
</section>
<!-- end slider section -->
</div>
<!-- explaining section -->
<div class="container">
</div>
</div>
<!-- about section -->
<section class="about_section layout_padding">
<!-- about section -->
<section class="about_section layout_padding section-animate-left" @ref="animatedAboutSection1">
<div class="container">
<div class="row">
<div class="col-md-6">
@ -65,9 +63,9 @@
</div>
</div>
</section>
</section>
<section class="about_section layout_padding">
<section class="about_section layout_padding section-animate-right" @ref="animatedAboutSection2">
<div class="container">
<div class="row">
<div class="col-md-6">
@ -101,5 +99,46 @@
</div>
</div>
</section>
</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,6 +42,8 @@
<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>
@ -63,6 +65,7 @@
<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<EFBFBD>ckner.Data;
using KIKunstKirstenKlöckner.Data;
using Radzen;
var builder = WebApplication.CreateBuilder(args);

View File

@ -35,6 +35,9 @@
<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

@ -11,20 +11,20 @@
"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": "Der O.G.",
"StableDiffusionModel": "Nacken/ki-kunst-kirsten-kloeckner-colab",
"PromptFormat": "{0} kkkk"
},
{
"Name": "SDXL 18000",
"StableDiffusionModel": "Nacken/kkk-sdxl-18000",
"PromptFormat": "kkkk {0}"
"Name": "Gen 25",
"StableDiffusionModel": "Nacken/Gen_25_Refiner",
"PromptFormat": "{0}"
}
],
"ConnectionStrings": {

View File

@ -0,0 +1,63 @@
.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;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 332 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 133 KiB

View File

@ -0,0 +1,52 @@
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);
};
}

7
global.json Normal file
View File

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