Compare commits

...

20 Commits

Author SHA1 Message Date
247c913051 redesign vom bilder generieren 2023-10-11 18:31:25 +02:00
80c7dca613 ein paar kleinigkeiten (schöner) in der nav bar gemacht + social links hinzugefügt 2023-10-11 18:10:37 +02:00
e4821d2d7e Refactoring 2023-10-11 15:11:29 +02:00
9c298c6e76 Gallerie zumindest etwas schicker gemacht 2023-10-10 20:21:06 +02:00
150cb24ce8 Merge branch 'Datenbank' 2023-10-10 20:20:02 +02:00
e6a2db0753 Gallery verwendet Datenbank
- Menü: Fixed typo in Gallerie
- Datenbanken-Funktionen dokumentiert
2023-10-10 18:56:05 +02:00
1b28481b5d Daten in Wunsch- und Bilddatenbanken speichern 2023-10-10 18:18:17 +02:00
d3c0737bfe Biisl Arsch verspeist 2023-10-10 17:39:37 +02:00
d0d9cb8bb3 Start of Datenbank 2023-10-10 16:21:00 +02:00
20c3408537 Update test_prompt2.txt 2023-10-10 14:32:52 +02:00
f10f991542 Das hat es irgendwie besser gemacht 2023-10-10 14:14:15 +02:00
b9054b485a Resolution hinzugefügt
Und zurückgeschraubt auf 3.5
2023-09-21 12:25:11 +02:00
11e9a930a1 Bildanzeige auf Größe Skaliert 2023-09-20 15:43:10 +02:00
72d2b788f2 Krasses SDXL Versionagé 2023-09-20 15:18:21 +02:00
77aa98a493 Merge branch 'main' of https://gitfrieds.nackenbox.xyz/Gottfried/KI-Kunst-Kirsten-Kloeckner 2023-09-20 12:24:08 +02:00
22351d0e1d Krasse Ideen von Mr. GPT 2023-09-20 12:22:52 +02:00
fb0397694a Fixibus den Überhang und Menü funktioniert 2023-09-20 12:20:36 +02:00
0b9427e9e5 Ki-Wunschprogramm zur Website 2023-08-18 15:01:56 +02:00
705146cb8b Ein paar Websiten hinzugefügt 2023-08-18 14:57:12 +02:00
31c3e33b11 Layout hinzugefügt, bisher eine Seite ohne funktion 2023-08-18 13:53:01 +02:00
78 changed files with 17480 additions and 528 deletions

View File

@ -0,0 +1,48 @@
using DataAccess.DbAccess;
using DataAccess.Models;
namespace DataAccess.Data;
/// <summary>
/// Ermöglicht den Zugriff auf die BildInfo Datenbank.
/// </summary>
public class BildInfoData
{
private readonly ISqlDataAccess _db;
public BildInfoData(ISqlDataAccess db)
{
_db = db;
}
/// <summary>
/// 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 AddBildInfoAsync(BildInfoModel bildInfo)
{
var id = await _db.LoadData<int, BildInfoModel>("dbo.spBildInfo_Insert", bildInfo);
bildInfo.Id = id.Single();
}
/// <summary>
/// Aktualisiert das Dateiname-Feld der übergebenen BildInfo in der Datenbank.
/// </summary>
/// <param name="bildInfo">Die BildInfo deren Dateiname aktualisiert werden soll.</param>
public Task UpdateBildInfoDateinameAsync(BildInfoModel bildInfo)
{
return _db.SaveData("dbo.spBildInfo_UpdateFileName",
new {
Id = bildInfo.Id,
Dateiname = bildInfo.Dateiname,
});
}
/// <summary>
/// Gibt alle Bild Infos der Datenbank zurück.
/// </summary>
public Task<IEnumerable<BildInfoModel>> GetAllBildInfosAsync()
{
return _db.LoadData<BildInfoModel, dynamic>("dbo.spBildInfo_GetAll", new { });
}
}

View File

@ -0,0 +1,36 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using DataAccess.DbAccess;
using DataAccess.Models;
namespace DataAccess.Data;
public class WunschInfoData
{
private readonly ISqlDataAccess _db;
public WunschInfoData(ISqlDataAccess db)
{
_db = db;
}
public async Task AddWunschInfoAsync(WunschInfoModel wunschInfo)
{
var id = await _db.LoadData<int, WunschInfoModel>("dbo.spWunschInfo_Insert", wunschInfo);
wunschInfo.Id = id.Single();
}
/// <summary>
/// Gibt die WunschInfo mit der gegebenen Id zurück.
/// </summary>
/// <param name="wunschId">Die Id der zu ladenen WunschInfo</param>
/// <returns>Die WunschInfo mit der gegebenen Id</returns>
public async Task<WunschInfoModel> GetWunschInfoAsync(int wunschId)
{
var wunschInfo = await _db.LoadData<WunschInfoModel, dynamic>("dbo.spWunschInfo_Get", new { Id = wunschId });
return wunschInfo.Single();
}
}

View File

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

View File

@ -0,0 +1,26 @@
namespace DataAccess.DbAccess;
/// <summary>
/// Bietet lesenden und schreibenden Zugriff auf eine Datenbank.
/// </summary>
public interface ISqlDataAccess
{
/// <summary>
/// Führt die angegebene Stored Procedure aus. Diese Prozedur nimmt Parameter des Typs <see cref="TParameter"/> engegen und gibt ein Enumerable des Typs <see cref="TResult"/> zurück.
/// </summary>
/// <typeparam name="TResult">Der Typ der Parameter</typeparam>
/// <typeparam name="TParameter">Der Typ der Rückgabewerte</typeparam>
/// <param name="storedProcedure">Der Name der Prozedur</param>
/// <param name="parameters">Die Parameter für die Prozedur.</param>
/// <param name="connectionId">Die optionale Id des zu verwendenen Connection Strings.</param>
Task<IEnumerable<TResult>> LoadData<TResult, TParameter>(string storedProcedure, TParameter parameters, string connectionId = "Default");
/// <summary>
/// Führt die angegebene Stored Procedure aus. Diese Prozedur nimmt Parameter des Typs <see cref="TParameter"/> engegen und gibt nichts zurück.
/// </summary>
/// <typeparam name="TParameter">Der Typ der Parameter</typeparam>
/// <param name="storedProcedure">Der Name der Prozedur</param>
/// <param name="parameters">Die Parameter für die Prozedur.</param>
/// <param name="connectionId">Die optionale Id des zu verwendenen Connection Strings.</param>
Task SaveData<TParameter>(string storedProcedure, TParameter parameters, string connectionId = "Default");
}

View File

@ -0,0 +1,33 @@
using Microsoft.Extensions.Configuration;
using System.Data.SqlClient;
using System.Data;
using Dapper;
namespace DataAccess.DbAccess;
/// <summary>
/// Bietet lesenden und schreibenden Zugriff auf eine Datenbank.
/// </summary>
public class SqlDataAccess : ISqlDataAccess
{
private readonly IConfiguration _config;
public SqlDataAccess(IConfiguration config)
{
_config = config;
}
public async Task<IEnumerable<TResult>> LoadData<TResult, TParameter>(string storedProcedure, TParameter parameters, string connectionId = "Default")
{
using IDbConnection connection = new SqlConnection(_config.GetConnectionString(connectionId));
return await connection.QueryAsync<TResult>(storedProcedure, parameters, commandType: CommandType.StoredProcedure);
}
public async Task SaveData<TParameter>(string storedProcedure, TParameter parameters, string connectionId = "Default")
{
using IDbConnection connection = new SqlConnection(_config.GetConnectionString(connectionId));
await connection.ExecuteAsync(storedProcedure, parameters, commandType: CommandType.StoredProcedure);
}
}

View File

@ -0,0 +1,10 @@
namespace DataAccess.Models;
public class BildInfoModel
{
public int Id { get; set; }
public DateTime Datum { get; set; }
public string Dateiname { get; set; }
public string ImageModel { get; set; }
public int WunschId { get; set; }
}

View File

@ -0,0 +1,11 @@
namespace DataAccess.Models;
public class WunschInfoModel
{
public int Id { get; set; }
public string BildPrompt { get; set; }
public string Wunsch { get; set; }
public string BildBeschreibung { get; set; }
public DateTime Datum { get; set; }
public string GPTModel { get; set; }
}

View File

@ -5,6 +5,10 @@ VisualStudioVersion = 17.6.33829.357
MinimumVisualStudioVersion = 10.0.40219.1 MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "KIKunstKirstenKlöckner", "KIKunstKirstenKlöckner\KIKunstKirstenKlöckner.csproj", "{0085541E-50D4-42A5-9BFD-6CE402FB8B26}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "KIKunstKirstenKlöckner", "KIKunstKirstenKlöckner\KIKunstKirstenKlöckner.csproj", "{0085541E-50D4-42A5-9BFD-6CE402FB8B26}"
EndProject 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}"
EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU Debug|Any CPU = Debug|Any CPU
@ -15,6 +19,16 @@ Global
{0085541E-50D4-42A5-9BFD-6CE402FB8B26}.Debug|Any CPU.Build.0 = Debug|Any CPU {0085541E-50D4-42A5-9BFD-6CE402FB8B26}.Debug|Any CPU.Build.0 = Debug|Any CPU
{0085541E-50D4-42A5-9BFD-6CE402FB8B26}.Release|Any CPU.ActiveCfg = Release|Any CPU {0085541E-50D4-42A5-9BFD-6CE402FB8B26}.Release|Any CPU.ActiveCfg = Release|Any CPU
{0085541E-50D4-42A5-9BFD-6CE402FB8B26}.Release|Any CPU.Build.0 = Release|Any CPU {0085541E-50D4-42A5-9BFD-6CE402FB8B26}.Release|Any CPU.Build.0 = Release|Any CPU
{A19CD19A-FE5B-4D4E-896B-DCC43B45F734}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{A19CD19A-FE5B-4D4E-896B-DCC43B45F734}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A19CD19A-FE5B-4D4E-896B-DCC43B45F734}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
{A19CD19A-FE5B-4D4E-896B-DCC43B45F734}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A19CD19A-FE5B-4D4E-896B-DCC43B45F734}.Release|Any CPU.Build.0 = Release|Any CPU
{A19CD19A-FE5B-4D4E-896B-DCC43B45F734}.Release|Any CPU.Deploy.0 = Release|Any CPU
{0880FD07-236B-42C1-9CA3-2A6F695A623C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{0880FD07-236B-42C1-9CA3-2A6F695A623C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{0880FD07-236B-42C1-9CA3-2A6F695A623C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{0880FD07-236B-42C1-9CA3-2A6F695A623C}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection EndGlobalSection
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE HideSolutionNode = FALSE

View File

@ -0,0 +1,12 @@
{
"version": 1,
"isRoot": true,
"tools": {
"dotnet-ef": {
"version": "7.0.9",
"commands": [
"dotnet-ef"
]
}
}
}

View File

@ -0,0 +1,16 @@
namespace KIKunstKirstenKlöckner.Data;
/// <summary>
/// Enthält Daten für die AiArt
/// </summary>
public class AiArtPageData
{
private readonly ImageGenerator _imageGenerator;
public ImageGenerator ImageGenerator => _imageGenerator;
public AiArtPageData(ImageGenerator imageGenerator)
{
_imageGenerator = imageGenerator;
}
}

View File

@ -0,0 +1,6 @@
namespace KIKunstKirstenKlöckner.Data;
public class ChatGPT
{
}

View File

@ -0,0 +1,105 @@
using DataAccess.Data;
using DataAccess.Models;
using Radzen;
using System.Diagnostics;
namespace KIKunstKirstenKlöckner.Data;
public class ImageGenerator
{
private readonly HttpClient _client = new();
private readonly BildInfoData _bildInfoData;
public ImageGenerator(IConfiguration config, BildInfoData bildInfoData)
{
_bildInfoData = bildInfoData;
string? inferenceApiKey = config.GetValue<string>("API:HF_Inference");
_client.DefaultRequestHeaders.Clear();
_client.DefaultRequestHeaders.Add("Authorization", $"Bearer {inferenceApiKey}");
}
/// <summary>
/// Geneiert das Bild für den aktuellen <see cref="_imagePrompt"/>
/// </summary>
public async Task<string?> GenerateImageAsync(string prompt, string negativePromt, int? width, int? height, WunschInfoModel wunschInfo, bool isRetry = false)
{
var postData = new
{
inputs = prompt,
parameters = new
{
negative_prompt = negativePromt, //"photorealistic, highly detailed, 8K, portrait",
width = width,
height = height
},
options = new
{
// Cache deaktivieren, damit Huggingface für den selben Prompt unterschiedliche Ergebnisse liefert
use_cache = false,
// Erst wenn wir bereits in einem retry sind warten wir implizit auf das Model. (ignoriert quasi 503-Fehler)
wait_for_model = true
}
};
JsonContent content = JsonContent.Create(postData);
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);
if (response?.IsSuccessStatusCode == true)
{
await using Stream imageStream = await response.Content.ReadAsStreamAsync();
using Image image = await Image.LoadAsync(imageStream);
DateTime imageDate = DateTime.Now;
BildInfoModel bildInfo = new()
{
Dateiname = "PlaceHolder",
Datum = imageDate,
ImageModel = modelName,
WunschId = wunschInfo.Id
};
await _bildInfoData.AddBildInfoAsync(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
{
Console.WriteLine($"Image conversion failed: {response}");
if (Debugger.IsAttached)
Debugger.Break();
return null;
}
}
catch (Exception exception)
{
Console.WriteLine($"Image request failed: {exception}");
if (Debugger.IsAttached)
Debugger.Break();
return null;
}
}
}

View File

@ -20,4 +20,8 @@
<PackageReference Include="SixLabors.ImageSharp" Version="3.0.1" /> <PackageReference Include="SixLabors.ImageSharp" Version="3.0.1" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<ProjectReference Include="..\DataAccess\DataAccess.csproj" />
</ItemGroup>
</Project> </Project>

View File

@ -1,110 +1,142 @@
@page "/"
@page "/aiart" @page "/aiart"
@using OpenAI_API @using OpenAI_API
@using OpenAI_API.Chat @using OpenAI_API.Chat
@using OpenAI_API.Models @using OpenAI_API.Models
@using System.Diagnostics @using DataAccess.Data
@using DataAccess.Models
@using KIKunstKirstenKlöckner.Data
@inject IConfiguration Config @inject IConfiguration Config
@inject TooltipService TooltipService @inject TooltipService TooltipService
@inject NotificationService NotificationService
@inject DialogService DialogService @inject DialogService DialogService
@* @inject AiArtPageData AiArtData; *@
@inject WunschInfoData WunschInfoData;
@inject ImageGenerator ImageGenerator;
<PageTitle>AiArt</PageTitle> <PageTitle>AiArt</PageTitle>
<h1>Wunschbilder von KI nur für dich</h1> <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"> <RadzenStack Orientation="Orientation.Vertical" AlignItems="AlignItems.Center" Style="min-height:800px">
<RadzenButton Text="Zur Gallery" Click="@NavigateToGallery" /> <RadzenText TextStyle="TextStyle.H2">Nenne uns deinen Wunsch:</RadzenText>
<RadzenTextBox @bind-Value=@request Placeholder="Dein Wunsch"/>
<RadzenPanel AllowCollapse="true" Style="width: 500px;" Text="Mehr Optionen"> <RadzenText TextStyle="TextStyle.H2">Dein Wunsch:</RadzenText>
<ChildContent>
<RadzenCard class="rz-mt-4">
<RadzenStack Orientation="Orientation.Horizontal"
MouseEnter="@(args => ShowTemperatureTooltip(args))"
MouseLeave="TooltipService.Close"
AlignItems="AlignItems.Center" Wrap="FlexWrap.Wrap">
<RadzenText>Temperature:</RadzenText>
<RadzenSlider @bind-Value=@temperature TValue="float"
Step="0.1" Min="0.0m" Max="2.0m">
</RadzenSlider>
<RadzenText>@temperature</RadzenText>
</RadzenStack>
</RadzenCard>
</ChildContent>
</RadzenPanel>
<RadzenButton Visible=@_buttonVisible Click=@(async ()=> await DoStuff(true))>Generate</RadzenButton>
<RadzenPanel AllowCollapse="true" Style="width: 500px;" Text="Zeige Prompt"> <RadzenStack Orientation="Orientation.Horizontal" AlignItems="AlignItems.Center">
<ChildContent> <RadzenTextBox @bind-Value=@request Placeholder="..." />
<RadzenCard class="rz-mt-4"> <RadzenButton Visible=@_buttonVisible Click=@(async ()=> await GenerateImages(true))>Generieren</RadzenButton>
<RadzenStack Orientation="Orientation.Horizontal" </RadzenStack>
MouseEnter="@(args => ShowTemperatureTooltip(args))"
MouseLeave="TooltipService.Close"
AlignItems="AlignItems.Center" Wrap="FlexWrap.Wrap">
<RadzenText>@_imagePromptEnglish</RadzenText>
</RadzenStack>
</RadzenCard>
</ChildContent>
</RadzenPanel>
<RadzenText TextStyle="TextStyle.H4">Die Idee, die gemalt wird:</RadzenText> <!--
<RadzenPanel AllowCollapse="true" Style="width: 500px;" Text="Mehr Optionen">
<ChildContent>
<RadzenCard class="rz-mt-4">
<RadzenStack Orientation="Orientation.Horizontal"
MouseEnter="@(args => ShowTemperatureTooltip(args))"
MouseLeave="TooltipService.Close"
AlignItems="AlignItems.Center" Wrap="FlexWrap.Wrap">
<RadzenText>Temperature:</RadzenText>
<RadzenSlider @bind-Value=@_temperature TValue="float"
Step="0.1" Min="0.0m" Max="2.0m">
</RadzenSlider>
<RadzenText>@_temperature</RadzenText>
</RadzenStack>
<RadzenStack Orientation="Orientation.Horizontal"
AlignItems="AlignItems.Center" Wrap="FlexWrap.Wrap">
<RadzenText>Resolution:</RadzenText>
<RadzenStack Orientation="Orientation.Horizontal">
<RadzenNumeric ShowUpDown = "false" TValue = "int?" @bind-Value=@width />
x
<RadzenNumeric ShowUpDown = "false" TValue = "int?" @bind-Value=@height />
</RadzenStack>
</RadzenStack>
<RadzenStack Orientation="Orientation.Horizontal"
AlignItems="AlignItems.Center" Wrap="FlexWrap.Wrap">
<RadzenCheckBox @bind-Value=@_useGpt4>
Verwende Gibbidy 4
</RadzenCheckBox>
</RadzenStack>
</RadzenCard>
</ChildContent>
</RadzenPanel>
-->
<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>
<RadzenCard class="rz-mt-4" Style="width: 800px;"> <RadzenProgressBarCircular Visible=@_progressVisible ProgressBarStyle="ProgressBarStyle.Secondary" Value="100" ShowValue="false" Mode="ProgressBarMode.Indeterminate" />
<RadzenText>@_imageDescription</RadzenText> <RadzenText Visible=@_progressVisible TextStyle="TextStyle.H6" Text=@BusyMessage></RadzenText>
<RadzenImage Path=@_imageUrl></RadzenImage>
<RadzenText Visible=@_addonsVisible TextStyle="TextStyle.H2">Verändere hier dein Bild durch Worte:</RadzenText>
<RadzenTextBox Visible=@_addonsVisible @bind-Value=@addons Placeholder="z.B. Mehr Farben" />
<RadzenButton Visible=@_bothVisible Click=@(async ()=> await GenerateImages(false))>Generate</RadzenButton>
<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])" />
</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])" />
</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])" />
</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])" />
</RadzenColumn>
</RadzenRow>
</RadzenCard> </RadzenCard>
</RadzenStack>
</div>
</section>
<RadzenProgressBarCircular Visible=@_progressVisible ProgressBarStyle="ProgressBarStyle.Secondary" Value="100" ShowValue="false" Mode="ProgressBarMode.Indeterminate" />
<RadzenText Visible=@_progressVisible TextStyle="TextStyle.H6" Text=@BusyMessage></RadzenText>
<RadzenImage Path=@_imageUrl></RadzenImage>
<RadzenText Visible=@_addonsVisible TextStyle="TextStyle.H2">Verändere hier dein Bild durch Worte:</RadzenText>
<RadzenTextBox Visible=@_addonsVisible @bind-Value=@addons Placeholder="z.B. Mehr Farben" />
<RadzenButton Visible=@_bothVisible Click=@(async ()=> await DoStuff(false))>Generate</RadzenButton>
<RadzenCard>
<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])" />
</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])" />
</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])" />
</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])" />
</RadzenColumn>
</RadzenRow>
</RadzenCard>
</RadzenStack>
@code { @code {
/// <summary>
/// Wenn <see langword="true"/> wird GPT4 verwendet um die Idee zu interpretieren.
/// </summary>
private bool _useGpt4;
private int maxAddons = 2; private int maxAddons = 2;
private int amountOfAddons = 0; // wird später geändert private int amountOfAddons = 0; // wird später geändert
private string _imageDescriptionPrompt = "Zusätzlich zu dem Promt erkläre kurz auf deutsch, warum du dich für diese Umsetzung des Titels entschieden hast und gib zusätzlich eine Interpretation des Bildes an. Beginne diesen Teil immer mit \"Beschreibung: \". Zuletzt Beschreibe das Bild und die verbundenen Emotionen mit drei Worten und beginne den Teil mit \"Keywords: \".";
private bool _progressVisible = false; private bool _progressVisible = false;
private bool _buttonVisible = true; private bool _buttonVisible = true;
private bool _addonsVisible = false; private bool _addonsVisible = false;
private bool _bothVisible = false; private bool _bothVisible = false;
private bool _promptVisible = false;
public string BusyMessage { get; set; } = "Initial Message"; public string BusyMessage { get; set; } = "Initial Message";
@ -113,74 +145,40 @@
enum ImageState enum ImageState
{ {
//Hide = 0,
FadeOut, FadeOut,
FadeIn, FadeIn
//Show,
}
// Busy dialog from markup
async Task ShowBusyDialog()
{
await DialogService.OpenAsync("", ds =>
@<RadzenStack AlignItems="AlignItems.Center" Gap="2rem" Class="rz-p-12">
<RadzenProgressBarCircular ProgressBarStyle="ProgressBarStyle.Secondary" Value="100" ShowValue="false" Mode="ProgressBarMode.Indeterminate"/>
<RadzenText TextStyle="TextStyle.H6" Text=@BusyMessage></RadzenText>
</RadzenStack>, new DialogOptions() { ShowTitle = false, Style = "min-height:auto;min-width:auto;width:auto", CloseDialogOnEsc = false });
} }
async Task ShowImageDialog(string imageUrl) async Task ShowImageDialog(string imageUrl)
{ {
var result = await DialogService.OpenAsync("", ds => var result = await DialogService.OpenAsync("", ds =>
@<div class="d-flex justify-content-center align-items-center" style="height:100%;"> @<div>
<RadzenImage Path="@imageUrl"/> <RadzenImage Style="object-fit: contain; width: 100%; height:100%;" Path="@imageUrl"/>
</div>, new DialogOptions() { CloseDialogOnOverlayClick = true }); </div>, new DialogOptions() { CloseDialogOnOverlayClick = true });
} }
// Busy dialog from string
async Task BusyDialog(string message)
{
await DialogService.OpenAsync("", ds =>
{
RenderFragment content = b =>
{
b.OpenElement(0, "RadzenRow");
b.OpenElement(1, "RadzenColumn");
b.AddAttribute(2, "Size", "12");
b.AddContent(3, message);
b.CloseElement();
b.CloseElement();
};
return content;
}, new DialogOptions() { ShowTitle = false, Style = "min-height:auto;min-width:auto;width:auto", CloseDialogOnEsc = false });
}
void ShowTooltip(ElementReference elementReference, string text, TooltipOptions? options = null) => TooltipService.Open(elementReference, text, options); void ShowTooltip(ElementReference elementReference, string text, TooltipOptions? options = null) => TooltipService.Open(elementReference, text, options);
void ShowTemperatureTooltip(ElementReference elementReference) => TooltipService.Open(elementReference, ds => void ShowTemperatureTooltip(ElementReference elementReference) => TooltipService.Open(elementReference, ds =>
@<div> @<div>
Gibt an, wie <em>kreativ</em> ChatGPT sein soll.<br /> Gibt an, wie <em>kreativ</em> ChatGPT sein soll.<br/>
Ich glaube, eigentlich bedeutet es eher, wie <em>deterministisch</em> die Ausgabe ist.<br />
Bei 0.0 kommt immer fast die selbe Antwort. Bei zu hohen Werten kommt nur noch Schwachsinn.<br />
OpenAI empfielt einen Wert von ca. 0.9 für kreative Anwendungen.
</div> </div>
, ,
new() { Position = TooltipPosition.Bottom, Duration = null}); new() { Position = TooltipPosition.Bottom, Duration = null});
private string _imagePromptEnglish = ""; private string _imageIdea = "";
private string _imageDescription = "";
private string _imagePrompt = ""; private string _imagePrompt = "";
private float temperature = 0.9f; private float _temperature = 0.9f;
private int? width = 1024;
private int? height = 1024;
private string request = ""; private string request = "";
private string addons = ""; private string addons = "";
private OpenAIAPI _openAiApi; private OpenAIAPI _openAiApi;
private Conversation converse; private Conversation? _conversation;
private string _basePrompt; private string _basePrompt;
private string _ideaPrompt;
private string _imageUrl; private string _imageUrl;
@ -189,262 +187,165 @@
// _basePrompt = await File.ReadAllTextAsync($"{Directory.GetCurrentDirectory()}{@"\wwwroot\prompt.txt"}"); // _basePrompt = await File.ReadAllTextAsync($"{Directory.GetCurrentDirectory()}{@"\wwwroot\prompt.txt"}");
//} //}
private async Task FunnyMessageSwitcher_ImageGen(CancellationToken cancellationToken)
{
Stopwatch sw = Stopwatch.StartNew();
await Task.Delay(1000, cancellationToken);
await UpdateBusyMessage("Dauert noch eine Weile...");
await Task.Delay(1000, cancellationToken);
await UpdateBusyMessage("Gut Ding hat Weil...");
await Task.Delay(1000, cancellationToken);
await UpdateBusyMessage("Sach ma, was issn da l... achso, er ist auf Klo gegangen... Er ist bestimmt gleich wieder da...");
await Task.Delay(1000, cancellationToken);
await UpdateBusyMessage("Na, also langsam verlier ich hier die Geduld, ich dachte KI soll alles schneller machen...");
while (!cancellationToken.IsCancellationRequested)
{
await Task.Delay(1000, cancellationToken);
await UpdateBusyMessage($"Keine Sorge, er arbeitet noch. Die Bilder werden gemalt... ({sw.Elapsed.Seconds}s)");
}
}
async Task UpdateBusyMessage(string newMessage) async Task UpdateBusyMessage(string newMessage)
{ {
BusyMessage = newMessage; BusyMessage = newMessage;
await InvokeAsync(StateHasChanged); await InvokeAsync(StateHasChanged);
} }
private readonly HttpClient _client = new();
private string _inferenceApiKey = "";
private string _openAiApiKey = ""; private string _openAiApiKey = "";
protected override Task OnInitializedAsync() protected override async Task OnInitializedAsync()
{ {
_inferenceApiKey = Config.GetValue<string>("API:HF_Inference");
_openAiApiKey = Config.GetValue<string>("API:OpenAI"); _openAiApiKey = Config.GetValue<string>("API:OpenAI");
_openAiApi = new OpenAIAPI(_openAiApiKey); _openAiApi = new OpenAIAPI(_openAiApiKey);
var inferenceModelUrl = "https://api-inference.huggingface.co/models/Nacken/ki-kunst-kirsten-kloeckner-colab"; await base.OnInitializedAsync();
//_client.BaseAddress = new Uri(inferenceModelUrl);
_client.DefaultRequestHeaders.Clear();
_client.DefaultRequestHeaders.Add("Authorization", $"Bearer {_inferenceApiKey}");
return base.OnInitializedAsync();
} }
/// <summary> private void ClearOldGeneration()
/// Geneiert das Bild für den aktuellen <see cref="_imagePrompt"/>
/// </summary>
public async Task GenerateImageAsync()
{
var postData = new
{
inputs = _imagePrompt
};
JsonContent content = JsonContent.Create(postData);
async Task FailedToDrawImage()
{
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 GenerateImageAsync();
}
try
{
var inferenceModelUrl = "https://api-inference.huggingface.co/models/Nacken/ki-kunst-kirsten-kloeckner-colab";
var response = await _client.PostAsync(inferenceModelUrl, content);
if (response?.IsSuccessStatusCode == true)
{
await using Stream imageStream = await response.Content.ReadAsStreamAsync();
using Image image = await Image.LoadAsync(imageStream);
string imgUrl = $"generated_images/{DateTime.Now:dd_MM_yyyy_hh_mm_s}.jpg";
string mapPath = $"./wwwroot/{imgUrl}";
await image.SaveAsJpegAsync(mapPath);
_imageUrl = imgUrl;
}
else
{
Console.WriteLine($"Image conversion failed: {response}");
if (Debugger.IsAttached)
Debugger.Break();
await FailedToDrawImage();
}
}
catch (Exception exception)
{
Console.WriteLine($"Image request failed: {exception}");
if (Debugger.IsAttached)
Debugger.Break();
await FailedToDrawImage();
}
}
/// <summary>
/// Geneiert das Bild für den aktuellen <see cref="_imagePrompt"/>
/// </summary>
public async Task<string?> GenerateImageAsync(string prompt, bool isRetry = false)
{
var postData = new
{
inputs = prompt,
options = new
{
// Cache deaktivieren, damit Huggingface für den selben Prompt unterschiedliche Ergebnisse liefert
use_cache = false,
// Erst wenn wir bereits in einem retry sind warten wir implizit auf das Model. (ignoriert quasi 503-Fehler)
wait_for_model = true
}
};
JsonContent content = JsonContent.Create(postData);
async Task<string?> FailedToDrawImage()
{
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)
{
return await GenerateImageAsync(prompt, true);
}
return null;
}
try
{
var inferenceModelUrl = "https://api-inference.huggingface.co/models/Nacken/ki-kunst-kirsten-kloeckner-colab";
var response = await _client.PostAsync(inferenceModelUrl, content);
if (response?.IsSuccessStatusCode == true)
{
await using Stream imageStream = await response.Content.ReadAsStreamAsync();
using Image image = await Image.LoadAsync(imageStream);
string imgUrl = $"generated_images/{DateTime.Now:dd_MM_yyyy_hh_mm_s_fffffff}.jpg";
string mapPath = $"./wwwroot/{imgUrl}";
await image.SaveAsJpegAsync(mapPath);
// Hier speichern wir die Daten in die 'info_texts.txt'-Datei
string infoTextsPath = Path.Combine(_environment.WebRootPath, "generated_images", "info_texts.txt");
string desc = _imageDescription.Replace("\r\n", "").Replace("\n", "").Replace("\r", "");
string newLine = $"{imgUrl}: {request}, {desc}\n";
await File.AppendAllTextAsync(infoTextsPath, newLine);
return imgUrl;
}
else
{
Console.WriteLine($"Image conversion failed: {response}");
if (Debugger.IsAttached)
Debugger.Break();
return await FailedToDrawImage();
}
}
catch (Exception exception)
{
Console.WriteLine($"Image request failed: {exception}");
if (Debugger.IsAttached)
Debugger.Break();
return await FailedToDrawImage();
}
return null;
}
private async Task DoStuff(bool newPic)
{ {
// Bilder verbergen
for (int i = 0; i < 4; i++) for (int i = 0; i < 4; i++)
_imageStates[i] = ImageState.FadeOut; _imageStates[i] = ImageState.FadeOut;
_imageIdea = "";
_imagePrompt = "";
}
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 = _useGpt4 ? Model.GPT4 : Model.ChatGPTTurbo
};
_conversation = _openAiApi.Chat.CreateConversation(chatRequest);
// Wunsch an GPT senden und Bild Idee anfordern
_conversation.AppendUserInput(ideaBasePrompt + " " + request);
_imageIdea = await _conversation.GetResponseFromChatbotAsync();
// Bild Promt anfordern
_conversation.AppendUserInput(requestImagePrompt);
_imagePrompt = await _conversation.GetResponseFromChatbotAsync();
}
/// <summary>
/// Generiert Bilder oder aktualisiert sie mit dem neuen Prompt.
/// </summary>
/// <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... // 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(); //Task busyDialog = ShowBusyDialog();
_progressVisible = true; _progressVisible = true;
_buttonVisible = false; _buttonVisible = false;
if (converse == null || newPic) if (_conversation == null || generateNewImage)
{ {
ClearOldGeneration();
amountOfAddons = maxAddons; amountOfAddons = maxAddons;
_addonsVisible = false; _addonsVisible = false;
_bothVisible = _buttonVisible && _addonsVisible; _bothVisible = _buttonVisible && _addonsVisible;
await UpdateBusyMessage("Kirstens Assistent zerbricht sich über deine Idee den Kopf..."); await UpdateBusyMessage("Kirstens Assistent zerbricht sich über deine Idee den Kopf...");
_basePrompt = await File.ReadAllTextAsync($"{Directory.GetCurrentDirectory()}{@"/wwwroot/test_prompt.txt"}");
ChatRequest chatRequest = new ChatRequest await RequestImageIdeaAsync();
{
Temperature = temperature,
Model = Model.ChatGPTTurbo,
};
converse = _openAiApi.Chat.CreateConversation(chatRequest);
converse.AppendUserInput(_basePrompt + " " + request);
} }
else else
{ {
if (amountOfAddons > 0) throw new NotImplementedException("Verändern von Idees ist nicht implementiert");
{ // if (amountOfAddons > 0)
amountOfAddons--; // {
_bothVisible = _buttonVisible && _addonsVisible; // amountOfAddons--;
await UpdateBusyMessage("Kirstens Assistent passt das Bild an deine Wünsche an..."); // _bothVisible = _buttonVisible && _addonsVisible;
string addonsPrompt1 = "Erstelle einen neuen Prompt auf englisch mit den gleichen Restriktionen auf Basis des Alten mit folgender Anpassung: "; // await UpdateBusyMessage("Kirstens Assistent passt das Bild an deine Wünsche an...");
string addonsPrompt2 = ". Denke daran nur den Prompt zu generieren und noch keine Beschreibung oder ähnliches."; // 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.";
converse.AppendUserInput(addonsPrompt1 + addons + addonsPrompt2); // _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...");
WunschInfoModel wunschInfo = new()
{
BildBeschreibung = _imageIdea,
BildPrompt = _imagePrompt,
Datum = DateTime.Now,
GPTModel = _conversation.Model,
Wunsch = request
};
try
{
await WunschInfoData.AddWunschInfoAsync(wunschInfo);
}
catch (Exception e)
{
NotificationService.Notify(new NotificationMessage()
{
Summary = "Es ist ein Fehler aufgetreten, bitte versuche es erneut."
});
return;
}
int generatedImages = 0;
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
} }
} }
_imagePromptEnglish = await converse.GetResponseFromChatbotAsync();
_imagePrompt = _imagePromptEnglish;
_imagePrompt += " Watercolor + ink on paper, Pen drawing, wet-on-wet technique, dry-on-dry technique, dabbing technique.";
converse.AppendUserInput(_imageDescriptionPrompt);
_imageDescription = await converse.GetResponseFromChatbotAsync();
await UpdateBusyMessage("Kirstens Assistent hat eine Idee! Er wird sie nun malen...");
// Vier Bilder generieren
for (int i = 0; i < 4; i++)
{
_imageUrls[i] = await GenerateImageAsync(_imagePrompt);
_imageStates[i] = ImageState.FadeIn;
await InvokeAsync(StateHasChanged);
}
_progressVisible = false; _progressVisible = false;
_buttonVisible = true; _buttonVisible = true;
_promptVisible = true;
if (amountOfAddons > 0) if (amountOfAddons > 0)
{ {
_addonsVisible = true; _addonsVisible = true;
@ -457,17 +358,5 @@
_bothVisible = false; _bothVisible = false;
} }
} }
private void NavigateToGallery()
{
NavigationManager.NavigateTo("/gallery");
}
[Inject]
private NavigationManager NavigationManager { get; set; }
[Inject]
private IWebHostEnvironment _environment { get; set; }
} }

View File

@ -1,148 +1,70 @@
@page "/gallery" @page "/gallery"
<RadzenDataList WrapItems="@true" AllowPaging="true" Data="@imagePaths" PageSize="20" PagerHorizontalAlign="HorizontalAlign.Left" ShowPagingSummary="true" class="image-grid"> @using DataAccess.Data
<Template Context="imagePath"> @using DataAccess.Models
<div class="image-grid-item">
<RadzenCard Style="width: 200px; height: 200px; padding: 0; border: none;">
<RadzenButton Click="@(args => ShowImageInfo(imagePath))">
<RadzenImage Src="@imagePath" Style="width: 100%; height: 100%; object-fit: cover;" />
</RadzenButton>
</RadzenCard>
</div>
</Template>
</RadzenDataList>
<div class="image-popup" style="@popupStyle"> @inject DialogService DialogService;
<div class="image-popup-content"> @inject BildInfoData BildInfoData;
<div class="image-info"> @inject WunschInfoData WunschInfoData;
<RadzenImage Src="@selectedImage" Style="max-width: 100%; max-height: 300px; object-fit: contain;" />
<p>@infoText</p>
</div>
<div class="close-button">
<RadzenButton Text="Close" Click="CloseImageInfo" />
</div>
</div>
</div>
<style> <style>
.image-grid { .small-image {
background-color: white; /* Hintergrund der RadzenDataList weiß machen */ width: 10em;
height: 10em;
z-index: auto;
margin: 0.5em;
box-shadow: 0 4px 8px 0 rgba(0,0,0,0.2);
border-radius: 1em;
/* Gibt an, dass Änderungen an der transform-Eigenschaft innerhalb von 0.2s angewandt werden.*/
transition: transform 0.2s;
} }
.rz-data-list { /* Style, der angewendet wird, wenn über small-image gehovert wird. */
display: flex; .small-image:hover {
flex-wrap: wrap; transform: scale(1.1, 1.1);
justify-content: center; z-index: 100;
}
.image-grid-item {
margin: 5px;
}
.image-popup {
display: none;
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(255, 255, 255, 0.9); /* Weißer Hintergrund mit Transparenz */
z-index: 9999;
}
.image-popup-content {
display: flex;
flex-direction: row;
justify-content: space-between;
max-width: 800px;
max-height: 400px;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
padding: 20px;
border-radius: 5px;
background-color: white; /* Weißer Hintergrund für den Inhalt */
}
.image-info {
flex: 1;
display: flex;
flex-direction: column;
align-items: center;
}
.close-button {
flex: 0 0 auto;
display: flex;
align-items: flex-start;
justify-content: flex-end;
} }
</style> </style>
<RadzenDataList WrapItems="@true" AllowPaging="true" PageSize="40" Data="@_bildInfos" PagerHorizontalAlign="HorizontalAlign.Left" ShowPagingSummary="true">
<Template Context="bildInfo">
<RadzenImage class="small-image" Src="@bildInfo.Dateiname" Click="@(args => ShowImageDialog(bildInfo))" />
</Template>
</RadzenDataList>
@code { @code {
List<string> imagePaths = new List<string>(); IEnumerable<BildInfoModel>? _bildInfos;
string selectedImage;
string infoText = "Info Text";
string popupStyle = "display: none;";
protected override async Task OnInitializedAsync() protected override async Task OnInitializedAsync()
{ {
_bildInfos = await BildInfoData.GetAllBildInfosAsync();
await base.OnInitializedAsync(); await base.OnInitializedAsync();
// Get the physical path to the folder
string folderPath = Path.Combine(_environment.WebRootPath, "generated_images");
if (Directory.Exists(folderPath))
{
// Load the image file names from the folder
var imageFiles = Directory.GetFiles(folderPath, "*.jpg");
// Get the relative paths to the images
imagePaths = imageFiles.Select(file => file.Replace(_environment.WebRootPath, "").Replace("\\", "/")).ToList();
}
} }
private async void ShowImageInfo(string imagePath) async Task ShowImageDialog(BildInfoModel bildInfo)
{ {
selectedImage = imagePath; WunschInfoModel wunschInfo = await WunschInfoData.GetWunschInfoAsync(bildInfo.WunschId);
popupStyle = "display: block;";
infoText = await GetInfoTextForImageAsync(imagePath);
}
List<BildInfoModel> bilderVomWunsch = _bildInfos!.Where(info => info.WunschId == wunschInfo.Id).ToList();
private async Task<string> GetInfoTextForImageAsync(string imagePath) var result = await DialogService.OpenAsync(wunschInfo.Wunsch, ds =>
{ @<div>
// Bestimme den Ordnerpfad, in dem sich die Bilder und die info_texts.txt Datei befinden <RadzenStack Orientation="Orientation.Horizontal" Wrap="FlexWrap.Wrap">
string folderPath = Path.Combine(_environment.WebRootPath, "generated_images"); <RadzenStack Orientation="Orientation.Horizontal">
<RadzenStack Orientation="Orientation.Vertical">
// Bestimme den Pfad zur info_texts.txt Datei <RadzenImage Style="width: 400px; height: 400px;" Path="@bildInfo.Dateiname" />
string infoTextsFilePath = Path.Combine(folderPath, "info_texts.txt"); </RadzenStack>
<RadzenText Text="@wunschInfo.BildBeschreibung"/>
// Überprüfe, ob die Datei existiert </RadzenStack>
if (!File.Exists(infoTextsFilePath)) @foreach (var bild in bilderVomWunsch)
return $"Kein Infotext für {imagePath} gefunden."; {
<RadzenImage class="small-image" Path="@bild.Dateiname"
// Lies alle Zeilen der Datei Click="async () => { bildInfo = bild; DialogService.Close(); await ShowImageDialog(bild); }" />
var lines = await File.ReadAllLinesAsync(infoTextsFilePath); }
string adaptedImagePath = imagePath.Substring(1) + ":"; </RadzenStack>
</div>,
// Durchsuche jede Zeile nach dem gegebenen imagePath new DialogOptions() { CloseDialogOnOverlayClick = true, Width = "50%" });
foreach (var line in lines)
{
if (line.StartsWith(adaptedImagePath)) // Überprüft, ob die Zeile mit dem Dateinamen des Bildes beginnt
{
// Trenne den Dateinamen und den Infotext und gib den Infotext zurück
return line.Split(new[] { ':' }, 2).LastOrDefault()?.Trim();
}
}
return $"Kein Infotext für {imagePath} gefunden.";
}
private void CloseImageInfo()
{
popupStyle = "display: none;";
} }
[Inject] [Inject]

View File

@ -0,0 +1,151 @@

@page "/"
<div class="hero_area">
<!-- slider section -->
<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 ">
<div class="detail_box">
<h1>
Wo Wünsche <br>
Wirklichkeit <br>
werden
</h1>
<p>
Willkommen auf meiner Webseite, wo Kunst und Technologie sich treffen. Ich freue mich, euch "Meine Wunschprogramm-Assistentin" vorzustellen, ein Projekt, das mir am Herzen liegt und das meine künstlerische Reise in eine aufregende neue Richtung führt.
</p>
<a href="/aiart" class="">
Probier es aus!
</a>
</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">
<div class="carousel-item active">
<div class="img-box">
<img src="images/keks.jpg" alt="">
</div>
</div>
<div class="carousel-item">
<div class="img-box">
<img src="images/slider-img2.jpg" alt="">
</div>
</div>
<div class="carousel-item">
<div class="img-box">
<img src="images/slider-img3.jpg" alt="">
</div>
</div>
</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>
<!-- explaining section -->
<div class="container">
</div>
<!-- about section -->
<section class="about_section layout_padding">
<div class="container">
<div class="row">
<div class="col-md-6">
<div class="img_container">
<div class="img-box b1">
<img src="images/about4.jpg" alt="" />
</div>
</div>
</div>
<div class="col-md-6">
<div class="detail-box">
<div class="heading_container">
<h2>
Was ist der Wunschprogramm-Assistent?
</h2>
<img src="images/plug.png" alt="">
</div>
<p>
Seit Jahren habe ich Wünsche in Aquarelle verwandelt, sie humorvoll und ironisch interpretiert und ihnen eine neue Dimension gegeben. Jetzt habe ich einen mutigen Schritt gemacht und Künstliche Intelligenz (KI) als meine persönliche Assistentin in dieses kreative Unterfangen einbezogen.
Auf meiner Webseite Wunschprogramm.ai könnt ihr nun eure Wünsche äußern, die von meiner Wunschprogramm-Assistentin umgesetzt werden. Egal, ob es sich um einen „Happy End“, „Anerkennung“, „Ein Sportwagen“ oder „Sanfter Tod“ handelt, ich interpretiere eure Wünsche fantasievoll und gebe ihnen eine neue inhaltliche Dimension. Die „Wunschprogramm-Assistentin“ generiert in wenigen Momenten ein Bild, das ihr bestellen könnt. Wenn euch die Bilder gefallen, könnt ihr sie als hochwertigen Kunstdruck bestellen, und ich werde sie für euch als Originale handsignieren.
</p>
<a href="">
Read More
</a>
</div>
</div>
</div>
</div>
</section>
<section class="about_section layout_padding">
<div class="container">
<div class="row">
<div class="col-md-6">
<div class="detail-box">
<div class="heading_container">
<img src="images/plug.png" alt="">
</div>
<p>
Auch politische Persönlichkeiten wie Bundespräsident Frank Walter Steinmeier oder Katarina Barley sowie show-Promis wie Micaela Schäfer und Carlo von Tiedemann haben mir bereits ihre Wünsche anvertraut, und ich lade euch ein, dasselbe zu tun. Es ist eine Gelegenheit, Teil eines kreativen Dialogs zu werden, der über die traditionellen Grenzen der Kunst hinausgeht.
Auf dieser Webseite findet ihr alle Informationen über mein bisheriges Wunschprogramm, über meinen künstlerischen Werdegang und über die Entstehung und Realisierung dieses Projektes. "Meine Wunschprogramm-Assistentin" ist mehr als nur ein Projekt; es ist eine Erkundung dessen, was Kunst sein kann, wenn sie mit der Technologie von heute verknüpft wird. Ich lade euch ein, diese Reise mit mir zu teilen, eure Wünsche zu äußern und zu sehen, wie sie in Kunst verwandelt werden.
Besucht Wunschprogramm.ai und entdeckt, was möglich ist, wenn Wünsche, Kunst und Technologie aufeinandertreffen. Ich freue mich darauf, eure Wünsche in Kunst zu verwandeln.
</p>
<a href="">
Read More
</a>
</div>
</div>
<div class="col-md-6">
<div class="img_container">
<div class="img-box b1">
<img src="images/about1.jpg" alt="" />
</div>
<div class="img-box b2">
<img src="images/about2.jpg" alt="" />
</div>
</div>
</div>
</div>
</div>
</section>
<!-- end about section -->

View File

@ -0,0 +1,139 @@
@page "/kirstenkloeckner"
<div class="hero_area">
<!-- slider section -->
<section class=" slider_section ">
<div class="container">
<div class="row">
<div class="col-md-6 ">
<div class="detail_box">
<h1>
Wer ist <br>
Kirsten <br>
Klöckner?
</h1>
<p>
Kirsten Klöckner, geboren 1962 in Braunschweig, hat die deutsche Kunstszene mit ihren humorvollen und hintergründigen Arbeiten bereichert.
</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">
<div class="carousel-item active">
<div class="img-box">
<img src="images/slider-img1.jpg" alt="">
</div>
</div>
<div class="carousel-item">
<div class="img-box">
<img src="images/slider-img2.jpg" alt="">
</div>
</div>
<div class="carousel-item">
<div class="img-box">
<img src="images/slider-img3.jpg" alt="">
</div>
</div>
</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>
<!-- explaining section -->
<div class="container">
</div>
<!-- about section -->
<section class="about_section layout_padding">
<div class="container">
<div class="row">
<div class="col-md-6">
<div class="img_container">
<div class="img-box b1">
<img src="images/about4.jpg" alt="" />
</div>
</div>
</div>
<div class="col-md-6">
<div class="detail-box">
<div class="heading_container">
<h2>
Was ist der Wunschprogramm-Assistent?
</h2>
<img src="images/plug.png" alt="">
</div>
<p>
Ihre kreative Reise begann mit einem Studium der Bildhauerei an der Kunstakademie Münster, wo sie von 1983 bis 1986 unter der Leitung von Reiner Ruthenbeck studierte. Nach ihrem Studium zog sie nach Düsseldorf, um dort bis 2001 zu leben und zu arbeiten. Berlin wurde 2002 ihr neues Zuhause, ein Ort, der ihr die Konzentration auf ihre Kunst ermöglichte.
Klöckner's künstlerische Ausbildung war geprägt von einer tiefen Leidenschaft für die Bildhauerei. Ihre Zeit in Münster legte den Grundstein für eine Karriere, die sich durch Vielseitigkeit und Kreativität auszeichnet. Nach ihrem Umzug nach Düsseldorf begann sie, ihre künstlerische Stimme zu finden, und Berlin bot ihr schließlich die Plattform, um sich voll und ganz auf ihre Kunst zu konzentrieren.
Ihr Werk ist vielseitig und reicht von Bildhauerei über Malerei bis hin zur Verlagsarbeit. Seit den 1990er Jahren produziert sie Multiples, kleine Objekte in begrenzter Auflagenzahl, die am Rand des Kunstmarkts gehandelt, geliebt und verschenkt werden. Ihr "Wunschbilder-Programm" ist ein zentrales Thema, in dem sie Wünsche ihrer Mitmenschen humorvoll und ironisch in Aquarellen umsetzt.
Im Laufe ihrer Karriere hat Kirsten Klöckner zahlreiche bemerkenswerte Ausstellungen gehabt, darunter "Science fiction, Teil 1: der Plan" (1992), "Eingemachtes" (1997), "Aquarelle + Multiples" (2004), und "Wunschbilder" (2015). Ihre Werke wurden in der Akademie der Künste in Berlin und in großen Galerien bundesweit ausgestellt. Sie hat auch an vielen Gruppenausstellungen teilgenommen, die ihre Vielseitigkeit und ihren Einfluss in der Kunstszene unterstreichen.
</p>
<a href="">
Read More
</a>
</div>
</div>
</div>
</div>
</section>
<section class="about_section layout_padding">
<div class="container">
<div class="row">
<div class="col-md-6">
<div class="detail-box">
<div class="heading_container">
<img src="images/plug.png" alt="">
</div>
<p>
Ihre Kunst ist in renommierten Sammlungen wie dem Kunstmuseum Düsseldorf, der Sammlung Falckenberg in Hamburg und der Kunstsammlung der Landesbank Baden-Württemberg in Stuttgart vertreten. Klöckner hat auch eine beeindruckende Liste von Veröffentlichungen, darunter "Heimatmelodie" (1989) und "Musenbesuch - BeuteKunst II" (2013), die einen tieferen Einblick in ihre kreativen Prozesse bieten.
Als "eine der humorvollsten" Künstlerinnen von Klaus Staeck, dem Präsidenten der Berliner Akademie der Künste, bezeichnet, wird Kirsten Klöckner sowohl von der Kunstgemeinschaft als auch von der breiten Öffentlichkeit geschätzt und anerkannt. Ihre kreative Zusammenarbeit mit APROTO - Aktionen und Projekte pro Toleranz - hat besondere Aufmerksamkeit erregt. Das „Toleranz-Virus“, ein Aquarell und eine Skulptur von Kirsten Klöckner, wurde umgesetzt, um Toleranz in schwierigen Zeiten zu fördern. Das Aquarell und die Skulptur werden als APROTO-Toleranzpreis verliehen.
Kirsten Klöckner's Reise durch die Kunstwelt ist eine, die von Humor, Intelligenz und einem unermüdlichen Streben nach kreativem Ausdruck geprägt ist. Ihre Werke und ihr Einfluss auf die Kunstszene zeugen von der Bedeutung und dem Wert ihrer Arbeit, und ihre fortwährende Innovation und ihr Engagement für Toleranz und Verständnis machen sie zu einer herausragenden Figur in der zeitgenössischen Kunst.
</p>
<a href="">
Read More
</a>
</div>
</div>
<div class="col-md-6">
<div class="img_container">
<div class="img-box b1">
<img src="images/about1.jpg" alt="" />
</div>
<div class="img-box b2">
<img src="images/about2.jpg" alt="" />
</div>
</div>
</div>
</div>
</div>
</section>
<!-- end about section -->

View File

@ -0,0 +1,137 @@
@page "/projekt"
<div class="hero_area">
<!-- slider section -->
<section class=" slider_section ">
<div class="container">
<div class="row">
<div class="col-md-6 ">
<div class="detail_box">
<h1>
Das <br>
Projekt <br>
</h1>
<p>
Zusammentreffen von Talent, Technologie und sozialer Verantwortung: Die Entstehung eines einzigartigen Projekts
</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">
<div class="carousel-item active">
<div class="img-box">
<img src="images/slider-img1.jpg" alt="">
</div>
</div>
<div class="carousel-item">
<div class="img-box">
<img src="images/slider-img2.jpg" alt="">
</div>
</div>
<div class="carousel-item">
<div class="img-box">
<img src="images/slider-img3.jpg" alt="">
</div>
</div>
</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>
<!-- explaining section -->
<div class="container">
</div>
<!-- about section -->
<section class="about_section layout_padding">
<div class="container">
<div class="row">
<div class="col-md-6">
<div class="img_container">
<div class="img-box b1">
<img src="images/about4.jpg" alt="" />
</div>
</div>
</div>
<div class="col-md-6">
<div class="detail-box">
<div class="heading_container">
<h2>
Wie entstand das Wunschprogramm Projekt?
</h2>
<img src="images/plug.png" alt="">
</div>
<p>
Das Projekt "Wunschprogramm-Assistentin" ist ein lebendiges Beispiel für kreative Zusammenarbeit, Innovation und Engagement, das sich selbstverständlich in einem ständigen Prozess der Entwicklung und Entfaltung befindet. Es vereint die Talente und Visionen von Künstlern, Journalisten, Studenten und einem engagierten Verein, um etwas wirklich Einzigartiges zu schaffen.
In enger Zusammenarbeit mit einem Team von IT-Studenten an der Leibniz-Universität in Hannover und dem Verein APROTO Aktionen und Projekte pro Toleranz, bringt die Berliner Künstlerin Kirsten Klöckner dieses einzigartige Projekt zum Leben. APROTO e.V., ein Verein, der sich für Toleranz und Verständigung einsetzt, hat bereits in der Vergangenheit durch Kunstprojekte Brücken zwischen verschiedenen Kulturen und Gesellschaftsgruppen gebaut.
Die Journalistin Meike Wolff, Vorstand von APROTO e.V., trägt durch ihre Texte und ihre Kommunikationsfähigkeiten dazu bei, das Projekt in die Öffentlichkeit zu bringen. Ihre Arbeit spiegelt den dynamischen Charakter des Projekts wider, das sich ständig weiterentwickelt und wächst.
</p>
<a href="">
Read More
</a>
</div>
</div>
</div>
</div>
</section>
<section class="about_section layout_padding">
<div class="container">
<div class="row">
<div class="col-md-6">
<div class="detail-box">
<div class="heading_container">
<img src="images/plug.png" alt="">
</div>
<p>
Die Idee zu diesem innovativen Projekt stammt von dem Journalisten Till-Matthias Jürgens. In enger Abstimmung mit den IT-Studenten und der Künstlerin Kirsten Klöckner überwacht er die Gesamtkonzeption und stellt sicher, dass das Projekt in Bewegung bleibt, sich anpasst und innovativ bleibt.
Die technische Umsetzung liegt in den fähigen Händen von Jan Kaminski, Meiko Remiorz, Simon Lübeß und Timm Kleipsties, KI-Studenten der Leibniz-Universität in Hannover. Sie arbeiten kontinuierlich an der Entwicklung des KI-Modells und seiner Daten-Einspeisung. Jan Kaminski, der auch für die grafische Umsetzung der Webseite verantwortlich ist, fungiert als kommunikative Schnittstelle und sorgt dafür, dass die technische und kreative Seite des Projekts nahtlos zusammenarbeiten.
Das Projekt "Wunschprogramm-Assistentin" ist mehr als nur eine künstlerische Unternehmung; es ist ein Zusammentreffen von Talent, Technologie und sozialer Verantwortung. Es zeigt, wie Kunst, Wissenschaft und Gemeinschaft zusammenarbeiten können, um etwas zu schaffen, das sowohl schön als auch bedeutungsvoll ist. Es ist ein Beweis dafür, dass die Grenzen zwischen diesen Bereichen nicht festgelegt sind und dass durch Zusammenarbeit und Innovation neue Wege beschritten werden können. Es ist ein aufregender Blick in die Zukunft der Kunst, eine Zukunft, die jetzt stattfindet, und ein Projekt, das sich in einem ständigen Prozess der Entdeckung und Erneuerung befindet.
</p>
<a href="">
Read More
</a>
</div>
</div>
<div class="col-md-6">
<div class="img_container">
<div class="img-box b1">
<img src="images/about1.jpg" alt="" />
</div>
<div class="img-box b2">
<img src="images/about2.jpg" alt="" />
</div>
</div>
</div>
</div>
</div>
</section>
<!-- end about section -->

View File

@ -0,0 +1,105 @@
@page "/wunschprogramm"
<div class="hero_area">
<!-- slider section -->
<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 ">
<div class="detail_box">
<h1>
Das <br>
Wunschprogramm
</h1>
<p>
Ich mache mich zur Komplizin der Wünschenden.
</p>
</div>
</div>
</div>
</div>
</section>
<!-- end slider section -->
</div>
<!-- explaining section -->
<div class="container">
</div>
<!-- about section -->
<section class="about_section layout_padding">
<div class="container">
<div class="row">
<div class="col-md-6">
<div class="img_container">
<div class="img-box b1">
<img src="images/about4.jpg" alt="" />
</div>
</div>
</div>
<div class="col-md-6">
<div class="detail-box">
<div class="heading_container">
<h2>
Was ist der Wunschprogramm-Assistent?
</h2>
<img src="images/plug.png" alt="">
</div>
<p>
Das Wunschprogramm von Kirsten Klöckner ist eine Reise in die Welt der Wünsche, eine faszinierende Verschmelzung von Kunst und menschlicher Sehnsucht. In einer Zeit, in der Kunst oft mit hohen Erwartungen konfrontiert ist, stellt Klöckner die Frage: Was, wenn Kunst auch Wünsche erfüllen könnte? Mit ihrem einzigartigen „Wunschbilder-Programm“ tut sie genau das.
Kirsten Klöckner hat sich auf die humorvolle und ironische Umwandlung von Wünschen ihrer Mitmenschen in Aquarelle spezialisiert. Sie interpretiert die Wünsche fantasievoll, gibt ihnen Substanz und verwandelt sie in Kunstwerke. Egal, ob es sich um einfache oder komplizierte Wünsche, kleine oder riesige, alberne oder ernsthafte Wünsche handelt, sie nimmt sie alle an und macht sie zu einem Teil ihres kreativen Prozesses. Selbst prominente Persönlichkeiten wie Bundespräsident Frank Walter Steinmeier und Showpromis wie Micaela Schäfer haben ihre Wünsche anvertraut.
</p>
<a href="">
Read More
</a>
</div>
</div>
</div>
</div>
</section>
<section class="about_section layout_padding">
<div class="container">
<div class="row">
<div class="col-md-6">
<div class="detail-box">
<div class="heading_container">
<img src="images/plug.png" alt="">
</div>
<p>
In ihren eigenen Worten beschreibt Klöckner das Wunschprogramm als eine Möglichkeit, sich etwas zu wünschen, in einer Welt, in der die Kunst oft schwer beschäftigt ist. „Ich lebe in einer Zeit, in der das Wünschen hilft“, sagt sie und fügt hinzu: „Ich mache mich zur Komplizin der Wünschenden.“
Das „Wunschprogramm“ von Kirsten Klöckner ist mehr als nur eine künstlerische Technik. Es ist eine Einladung, über unsere Wünsche nachzudenken und sie in die Welt der Kunst zu bringen. Es ist eine Möglichkeit, unsere tiefsten Sehnsüchte und Träume in einer Form zu sehen, die sowohl schön als auch nachdenklich ist. Es ist eine Erinnerung daran, dass die Kunst immer noch die Kraft hat, uns zu überraschen, zu inspirieren und uns etwas zu wünschen.
Die Kunst des Wünschens, wie sie von Klöckner praktiziert wird, ist ein lebendiger Dialog zwischen dem Künstler und dem Betrachter, eine Möglichkeit, die oft flüchtigen Gedanken und Sehnsüchte in etwas Greifbares und Bleibendes zu verwandeln. Es ist eine Reise, die uns alle einlädt, Teilnehmer und Zeugen der Transformation von Wünschen in Kunst zu sein, und es ist ein Beweis dafür, dass Kunst immer noch die Macht hat, uns auf unerwartete und wunderbare Weise zu berühren.
</p>
<a href="">
Read More
</a>
</div>
</div>
<div class="col-md-6">
<div class="img_container">
<div class="img-box b1">
<img src="images/about1.jpg" alt="" />
</div>
<div class="img-box b2">
<img src="images/about2.jpg" alt="" />
</div>
</div>
</div>
</div>
</div>
</section>
<!-- end about section -->

View File

@ -18,6 +18,31 @@
<!-- Radzen.Blazor --> <!-- Radzen.Blazor -->
<link rel="stylesheet" href="_content/Radzen.Blazor/css/humanistic-base.css"> <link rel="stylesheet" href="_content/Radzen.Blazor/css/humanistic-base.css">
<script src="_content/Radzen.Blazor/Radzen.Blazor.js"></script> <script src="_content/Radzen.Blazor/Radzen.Blazor.js"></script>
<!-- Basic -->
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<!-- Mobile Metas -->
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no" />
<!-- Site Metas -->
<meta name="keywords" content="" />
<meta name="description" content="" />
<meta name="author" content="" />
<title>KI Kunst Kirsten </title>
<!-- slider stylesheet -->
<link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/OwlCarousel2/2.1.3/assets/owl.carousel.min.css" />
<!-- bootstrap core css -->
<link rel="stylesheet" type="text/css" href="css/bootstrap.css" />
<!-- fonts style -->
<link href="https://fonts.googleapis.com/css?family=Poppins:400,600,700&display=swap" rel="stylesheet">
<!-- Custom styles for this template -->
<link href="css/style.css" rel="stylesheet" />
<!-- responsive style -->
<link href="css/responsive.css" rel="stylesheet" />
</head> </head>
<body> <body>
<component type="typeof(App)" render-mode="ServerPrerendered" /> <component type="typeof(App)" render-mode="ServerPrerendered" />
@ -34,5 +59,10 @@
</div> </div>
<script src="_framework/blazor.server.js"></script> <script src="_framework/blazor.server.js"></script>
<script src="js/jquery-3.4.1.min.js"></script>
<script src="js/bootstrap.js"></script>
</body> </body>
</html> </html>

View File

@ -1,3 +1,6 @@
using DataAccess.Data;
using DataAccess.DbAccess;
using KIKunstKirstenKl<EFBFBD>ckner.Data;
using Radzen; using Radzen;
var builder = WebApplication.CreateBuilder(args); var builder = WebApplication.CreateBuilder(args);
@ -5,9 +8,17 @@ var builder = WebApplication.CreateBuilder(args);
// Add services to the container. // Add services to the container.
builder.Services.AddRazorPages(); builder.Services.AddRazorPages();
builder.Services.AddServerSideBlazor(); builder.Services.AddServerSideBlazor();
builder.Services.AddScoped<TooltipService>(); builder.Services.AddScoped<TooltipService>();
builder.Services.AddScoped<DialogService>(); builder.Services.AddScoped<DialogService>();
builder.Services.AddScoped<NotificationService>(); builder.Services.AddScoped<NotificationService>();
builder.Services.AddScoped<ImageGenerator>();
builder.Services.AddScoped<AiArtPageData>();
builder.Services.AddSingleton<ISqlDataAccess, SqlDataAccess>();
builder.Services.AddSingleton<BildInfoData>();
builder.Services.AddSingleton<WunschInfoData>();
var app = builder.Build(); var app = builder.Build();

View File

@ -3,17 +3,130 @@
<PageTitle>KIKunstKirstenKlöckner</PageTitle> <PageTitle>KIKunstKirstenKlöckner</PageTitle>
<div class="page"> <div class="page">
@*
<div class="sidebar">
<NavMenu />
</div>
*@
<main> <main>
<!-- header section strats -->
<header class="header_section">
<div class="container">
<nav class="navbar navbar-expand-lg custom_nav-container ">
<a class="navbar-brand" href="/">
<img src="images/robot_painting_small.jpg" alt="">
<span>
KI-Wunschprogramm
</span>
</a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<span class="s-1"> </span>
<span class="s-2"> </span>
<span class="s-3"> </span>
</button>
<div class="collapse navbar-collapse" id="navbarSupportedContent">
<div class="d-flex ml-auto flex-column flex-lg-row align-items-center">
<ul class="navbar-nav ">
<NavLink class="nav-item" href="" Match="NavLinkMatch.All">
<span class="nav-link">Start</span>
</NavLink>
<NavLink class="nav-item" href="aiart" Match="NavLinkMatch.All">
<span class="nav-link">Generieren</span>
</NavLink>
<NavLink class="nav-item" href="wunschprogramm" Match="NavLinkMatch.All">
<span class="nav-link">Wunschprogramm</span>
</NavLink>
<NavLink class="nav-item" href="kirstenkloeckner" Match="NavLinkMatch.All">
<span class="nav-link">Kirsten</span>
</NavLink>
<NavLink class="nav-item" href="gallery" Match="NavLinkMatch.All">
<span class="nav-link">Galerie</span>
</NavLink>
</ul>
</div>
</div>
</nav>
</div>
</header>
<!-- end header section -->
<article class="content px-4"> <article class="content px-4">
@Body @Body
</article> </article>
<!-- info section -->
<section class="info_section layout_padding">
<div class="container">
<div class="info_contact">
<div class="row">
<div class="col-md-4">
<a href="">
<img src="images/location-white.png" alt="">
<span>
Kirsten Klöckners KI-Atelier
</span>
</a>
</div>
<div class="col-md-4">
<a href="">
<img src="images/telephone-white.png" alt="">
<span>
+012334567890
</span>
</a>
</div>
<div class="col-md-4">
<a href="">
<img src="images/envelope-white.png" alt="">
<span>
nackenbox@gmail.com
</span>
</a>
</div>
</div>
</div>
<div class="row">
<div class="col-md-4 col-lg-3">
<div class="info_social">
<div>
<a href="https://www.facebook.com/kirsten.kloeckner">
<img src="images/fb.png" alt="">
</a>
</div>
<div>
<a href="https://twitter.com/kkbeutekunst">
<img src="images/twitter.png" alt="">
</a>
</div>
<div>
<a href="https://de.linkedin.com/in/kirsten-kl%C3%B6ckner-2a123393">
<img src="images/linkedin.png" alt="">
</a>
</div>
<div>
<a href="https://www.instagram.com/kirstenkloeckner/">
<img src="images/instagram.png" alt="">
</a>
</div>
</div>
</div>
</div>
</div>
</section>
<!-- end info section -->
<!-- footer section -->
<footer class="container-fluid footer_section">
<div class="container">
<div class="row">
<div class="col-lg-7 col-md-9 mx-auto">
<p>
&copy; 2022 All Rights Reserved By Nackenbox GMBH und Co. KG
</p>
</div>
</div>
</div>
</footer>
<!-- footer section -->
</main> </main>
</div> </div>

View File

@ -1,9 +1,12 @@
{ {
"DetailedErrors": true, "DetailedErrors": true,
"Logging": { "Logging": {
"LogLevel": { "LogLevel": {
"Default": "Information", "Default": "Information",
"Microsoft.AspNetCore": "Warning" "Microsoft.AspNetCore": "Warning"
}
},
"ConnectionStrings": {
"Default": "Data Source=(localdb)\\MSSQLLocalDB;Initial Catalog=KiKunstDatenbank;Integrated Security=True;Connect Timeout=60;Encrypt=False;TrustServerCertificate=False;ApplicationIntent=ReadWrite;MultiSubnetFailover=False"
} }
}
} }

View File

@ -9,5 +9,8 @@
"API": { "API": {
"OpenAI": "<put OpenAI Key here>", "OpenAI": "<put OpenAI Key here>",
"HF_Inference": "<put Hugging Face inference API Key here>" "HF_Inference": "<put Hugging Face inference API Key here>"
},
"ConnectionStrings": {
"Default": "<put Connection String here>"
} }
} }

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,118 @@
@media (max-width: 1120px) {}
@media (max-width: 992px) {
.hero_area {
height: auto;
}
.header_section {
padding-top: 10px;
}
#navbarSupportedContent {
margin-top: 25px;
}
.slider_section {
padding-top: 75px;
padding-bottom: 150px;
}
.about_section .img-box {
margin: 0 5%;
}
.about_section .detail-box {
margin-right: 5%;
}
.service_section .service_container .box {
-ms-flex-preferred-size: 48%;
flex-basis: 48%;
}
.about_section .img_container .img-box.b2 {
margin-top: -5%;
}
}
@media (max-width: 768px) {
.slider_section .detail_box {
text-align: center;
}
.slider_section .img_content {
margin-top: 55px;
}
.contact_section .map_container {
margin-top: 45px;
}
.info_section .info_contact a {
margin-bottom: 15px;
}
.info_section .info_social {
justify-content: center;
}
.service_section .service_container .box {
flex-basis: 98%;
}
.contact_section form {
padding-right: 0;
}
.info_section .info_contact a {
text-align: center;
}
}
@media (max-width: 576px) {
.about_section .img_container .img-box.b1 {
width: 80%;
}
.about_section .img_container .img-box.b2 {
width: 55%;
}
.info_section .info_form form {
flex-direction: column;
}
.info_section .info_form form input {
width: 100%;
}
.info_section .info_form form button {
margin-top: 15px;
padding: 10px 40px;
}
}
@media (max-width: 480px) {}
@media (max-width: 420px) {
.slider_section .carousel-control-prev,
.slider_section .carousel-control-next {
right: 0;
}
}
@media (max-width: 360px) {}
@media (min-width: 1200px) {
.container {
max-width: 1170px;
}
}

View File

@ -0,0 +1,693 @@
body {
font-family: "Poppins", sans-serif;
color: #0c0c0c;
background-color: #ffffff;
}
.layout_padding {
padding-top: 90px;
padding-bottom: 90px;
}
.layout_padding2 {
padding-top: 45px;
padding-bottom: 45px;
}
.layout_padding2-top {
padding-top: 45px;
}
.layout_padding2-bottom {
padding-bottom: 45px;
}
.layout_padding-top {
padding-top: 90px;
}
.layout_padding-bottom {
padding-bottom: 90px;
}
.heading_container {
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-webkit-box-pack: start;
-ms-flex-pack: start;
justify-content: flex-start;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
text-align: center;
}
.heading_container h2 {
position: relative;
font-weight: bold;
margin-right: 10px;
}
.heading_container img {
width: 30px;
}
/*header section*/
.hero_area {
height: 98vh;
position: relative;
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-webkit-box-orient: vertical;
-webkit-box-direction: normal;
-ms-flex-direction: column;
flex-direction: column;
background-color: #eae6f5;
}
.sub_page .hero_area {
height: auto;
}
.header_section .container {
padding: 0;
}
.header_section .nav_container {
margin: 0 auto;
}
.custom_nav-container .navbar-nav .nav-item .nav-link {
padding: 7px 20px;
margin: 10px 15px;
color: #000000;
text-align: center;
border-radius: 35px;
text-transform: uppercase;
font-size: 15px;
}
.custom_nav-container .navbar-nav .nav-item.active .nav-link, .custom_nav-container .navbar-nav .nav-item:hover .nav-link {
background-color: #4b208c;
color: #ffffff;
}
a,
a:hover,
a:focus {
text-decoration: none;
}
a:hover,
a:focus {
color: initial;
}
.btn,
.btn:focus {
outline: none !important;
-webkit-box-shadow: none;
box-shadow: none;
}
.custom_nav-container .nav_search-btn {
background-image: url(../images/search-icon.png);
background-size: 22px;
background-repeat: no-repeat;
background-position-y: 7px;
width: 35px;
height: 35px;
padding: 0;
border: none;
}
.navbar-brand {
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
}
.navbar-brand img {
margin-right: 5px;
width: 150px;
}
.navbar-brand span {
font-size: 22px;
font-weight: 700;
color: #4b208c;
}
.custom_nav-container {
z-index: 99999;
}
.navbar-expand-lg .navbar-collapse {
-webkit-box-align: end;
-ms-flex-align: end;
align-items: flex-end;
}
.custom_nav-container .navbar-toggler {
outline: none;
}
.custom_nav-container .navbar-toggler {
padding: 0;
width: 37px;
height: 42px;
}
.custom_nav-container .navbar-toggler span {
display: block;
width: 35px;
height: 4px;
background-color: #190734;
margin: 7px 0;
-webkit-transition: all .3s;
transition: all .3s;
}
.custom_nav-container .navbar-toggler[aria-expanded="true"] .s-1 {
-webkit-transform: rotate(45deg);
transform: rotate(45deg);
margin: 0;
margin-bottom: -4px;
}
.custom_nav-container .navbar-toggler[aria-expanded="true"] .s-2 {
display: none;
}
.custom_nav-container .navbar-toggler[aria-expanded="true"] .s-3 {
-webkit-transform: rotate(-45deg);
transform: rotate(-45deg);
margin: 0;
margin-top: -4px;
}
.custom_nav-container .navbar-toggler[aria-expanded="false"] .s-1,
.custom_nav-container .navbar-toggler[aria-expanded="false"] .s-2,
.custom_nav-container .navbar-toggler[aria-expanded="false"] .s-3 {
-webkit-transform: none;
transform: none;
}
/*end header section*/
/* slider section */
.slider_section {
-webkit-box-flex: 1;
-ms-flex: 1;
flex: 1;
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
position: relative;
z-index: 2;
color: #3b3a3a;
padding-bottom: 90px;
}
.slider_section .row {
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
}
.slider_section .detail_box {
color: #000000;
}
.slider_section .detail_box h1 {
text-transform: uppercase;
font-weight: bold;
}
.slider_section .detail_box p {
margin-top: 20px;
}
.slider_section .detail_box a {
display: inline-block;
padding: 10px 40px;
background-color: #4b208c;
color: #ffffff;
border-radius: 35px;
margin-top: 35px;
}
.slider_section .detail_box a:hover {
background-color: #5625a1;
}
.slider_section .img_container {
border: 7px solid #7b57b2;
border-radius: 100%;
overflow: hidden;
}
.slider_section .img_container div#carouselExampleContarols {
width: 100%;
position: unset;
}
.slider_section .img_container .img-box img {
width: 100%;
}
.slider_section .carousel-control-prev,
.slider_section .carousel-control-next {
top: initial;
left: initial;
bottom: 5%;
right: 10%;
width: 45px;
height: 45px;
border: none;
border-radius: 100%;
opacity: 1;
background-repeat: no-repeat;
background-size: 8px;
background-position: center;
}
.slider_section .carousel-control-prev {
background-image: url(../images/prev.png);
background-color: #ffffff;
-webkit-transform: translate(-85px, 30px);
transform: translate(-85px, 30px);
}
.slider_section .carousel-control-next {
background-image: url(../images/next.png);
background-color: #4b208c;
-webkit-transform: translate(-45px, 0);
transform: translate(-45px, 0);
}
.service_section {
text-align: center;
}
.service_section .heading_container {
-webkit-box-pack: center;
-ms-flex-pack: center;
justify-content: center;
}
.service_section .service_container {
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-webkit-box-pack: center;
-ms-flex-pack: center;
justify-content: center;
padding: 35px 0;
-ms-flex-wrap: wrap;
flex-wrap: wrap;
}
.service_section .service_container .box {
margin: 25px 1%;
-ms-flex-preferred-size: 31%;
flex-basis: 31%;
padding: 35px 25px 25px;
border-radius: 15px;
-webkit-box-shadow: 0 0 10px 0 rgba(0, 0, 0, 0.15);
box-shadow: 0 0 10px 0 rgba(0, 0, 0, 0.15);
border-top: 15px solid transparent;
overflow: hidden;
-webkit-transition: all .1s;
transition: all .1s;
}
.service_section .service_container .box .img-box {
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-webkit-box-pack: center;
-ms-flex-pack: center;
justify-content: center;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
height: 125px;
}
.service_section .service_container .box .img-box img {
width: 90px;
}
.service_section .service_container .box .detail-box {
margin-top: 25px;
}
.service_section .service_container .box .detail-box h5 {
color: #2e0e5f;
font-weight: 600;
position: relative;
}
.service_section .service_container .box:hover, .service_section .service_container .box.active {
border-top: 15px solid #512a97;
}
.service_section .btn-box {
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-webkit-box-pack: center;
-ms-flex-pack: center;
justify-content: center;
margin-top: 25px;
}
.service_section .btn-box a {
display: inline-block;
padding: 10px 35px;
background-color: #4b208c;
color: #ffffff;
border-radius: 35px;
}
.service_section .btn-box a:hover {
background-color: #5625a1;
}
.about_section {
background-color: #f3f0f6;
}
.about_section .row {
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
}
.about_section .img_container {
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-webkit-box-orient: vertical;
-webkit-box-direction: normal;
-ms-flex-direction: column;
flex-direction: column;
}
.about_section .img_container .img-box {
border: 5px solid #7b57b2;
border-radius: 100%;
overflow: hidden;
}
.about_section .img_container .img-box.b1 {
width: 70%;
}
.about_section .img_container .img-box.b2 {
width: 50%;
margin-left: auto;
margin-top: -12%;
}
.about_section .img_container .img-box img {
width: 100%;
}
.about_section .detail-box {
margin-right: 15%;
}
.about_section .detail-box p {
margin-top: 25px;
}
.about_section .detail-box a {
display: inline-block;
padding: 10px 35px;
background-color: #4b208c;
color: #ffffff;
border-radius: 5px;
margin: 25px 0 45px 0;
}
.about_section .detail-box a:hover {
background-color: #5625a1;
}
.blog_section .heading_container {
-webkit-box-pack: center;
-ms-flex-pack: center;
justify-content: center;
}
.blog_section .heading_container h2::before {
background-color: #ffffff;
}
.blog_section .box {
margin-top: 55px;
background-color: #ffffff;
-webkit-box-shadow: 0 0 10px 0 rgba(0, 0, 0, 0.15);
box-shadow: 0 0 10px 0 rgba(0, 0, 0, 0.15);
}
.blog_section .box .img-box {
position: relative;
}
.blog_section .box .img-box img {
width: 100%;
}
.blog_section .box .detail-box {
padding: 25px 25px 15px;
}
.blog_section .box .detail-box h5 {
font-weight: bold;
}
.contact_section {
position: relative;
}
.contact_section form {
margin-top: 45px;
padding-right: 35px;
}
.contact_section input {
width: 100%;
border: none;
height: 50px;
margin-bottom: 25px;
padding-left: 25px;
background-color: transparent;
outline: none;
color: #101010;
-webkit-box-shadow: 0px 2px 5px 0px rgba(0, 0, 0, 0.16);
box-shadow: 0px 2px 5px 0px rgba(0, 0, 0, 0.16);
}
.contact_section input::-webkit-input-placeholder {
color: #737272;
}
.contact_section input:-ms-input-placeholder {
color: #737272;
}
.contact_section input::-ms-input-placeholder {
color: #737272;
}
.contact_section input::placeholder {
color: #737272;
}
.contact_section input.message-box {
height: 120px;
}
.contact_section button {
border: none;
display: inline-block;
padding: 12px 45px;
background-color: #4b208c;
color: #ffffff;
border-radius: 0px;
margin-top: 35px;
}
.contact_section button:hover {
background-color: #5625a1;
}
.contact_section .map_container {
height: 100%;
min-height: 325px;
}
.contact_section .map_container .map-responsive {
height: 100%;
}
.footer_bg {
background-image: url(../images/footer-bg.png);
background-size: cover;
background-position: top;
}
/* info section */
.info_section {
background-color: #190734;
color: #ffffff;
}
.info_section h6 {
font-weight: bold;
}
.info_section .info_contact {
margin-top: 60px;
margin-bottom: 45px;
}
.info_section .info_contact .col-md-4 {
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-webkit-box-pack: center;
-ms-flex-pack: center;
justify-content: center;
}
.info_section .info_contact a {
color: #ffffff;
}
.info_section .info_contact img {
max-width: 100%;
margin-right: 10px;
}
.info_section .info_form {
margin: 0 auto;
margin-bottom: 45px;
}
.info_section .info_form h4 {
text-transform: uppercase;
text-align: center;
margin-bottom: 20px;
}
.info_section .info_form form {
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
}
.info_section .info_form form input {
background-color: #ffffff;
border: none;
-webkit-box-flex: 2.5;
-ms-flex: 2.5;
flex: 2.5;
outline: none;
color: #000000;
min-height: 42.4px;
padding-left: 15px;
}
.info_section .info_form form input ::-webkit-input-placeholder {
color: #ffffff;
opacity: 0.2;
}
.info_section .info_form form input :-ms-input-placeholder {
color: #ffffff;
opacity: 0.2;
}
.info_section .info_form form input ::-ms-input-placeholder {
color: #ffffff;
opacity: 0.2;
}
.info_section .info_form form input ::placeholder {
color: #ffffff;
opacity: 0.2;
}
.info_section .info_form form button {
-webkit-box-flex: 1;
-ms-flex: 1;
flex: 1;
border: none;
display: inline-block;
padding: 10px 30px;
background-color: #4b208c;
color: #ffffff;
border-radius: 0;
font-size: 15px;
text-transform: uppercase;
}
.info_section .info_form form button:hover {
background-color: #5625a1;
}
.info_section .box {
display: -webkit-box;
display: -ms-flexbox;
display: flex;
}
.info_section .info_social {
display: -webkit-box;
display: -ms-flexbox;
display: flex;
}
.info_section .info_social img {
width: 35px;
margin-right: 8px;
}
/* end info section */
/* footer section*/
.footer_section {
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-webkit-box-pack: center;
-ms-flex-pack: center;
justify-content: center;
position: relative;
}
.footer_section p {
color: #222222;
margin: 0 auto;
text-align: center;
padding: 20px;
}
.footer_section p a {
color: #222222;
}
/*# sourceMappingURL=style.css.map */

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,643 @@
$white: #ffffff;
$black: #000000;
$primary1: #4b208c;
$primary2: #371e71;
@mixin main-font {
font-family: "Poppins", sans-serif;
}
@mixin hero_btn($col1, $col2, $pad1, $pad2, $bRadius) {
display: inline-block;
padding: $pad1 $pad2;
background-color: $col1;
color: $col2;
border-radius: $bRadius;
&:hover {
background-color: lighten($color: $col1, $amount: 5);
}
}
@mixin upperBold {
text-transform: uppercase;
font-weight: bold;
}
body {
@include main-font;
color: #0c0c0c;
background-color: #ffffff;
}
.layout_padding {
padding-top: 90px;
padding-bottom: 90px;
}
.layout_padding2 {
padding-top: 45px;
padding-bottom: 45px;
}
.layout_padding2-top {
padding-top: 45px;
}
.layout_padding2-bottom {
padding-bottom: 45px;
}
.layout_padding-top {
padding-top: 90px;
}
.layout_padding-bottom {
padding-bottom: 90px;
}
.heading_container {
display: flex;
justify-content: flex-start;
align-items: center;
text-align: center;
h2 {
position: relative;
font-weight: bold;
margin-right: 10px;
}
img {
width: 30px;
}
}
/*header section*/
.hero_area {
height: 98vh;
position: relative;
display: flex;
flex-direction: column;
background-color: #eae6f5;
}
.sub_page {
.hero_area {
height: auto;
}
}
.header_section {
.container {
padding: 0;
}
.nav_container {
margin: 0 auto;
}
}
.custom_nav-container {
.navbar-nav {
.nav-item {
.nav-link {
padding: 7px 20px;
margin: 10px 15px;
color: $black;
text-align: center;
border-radius: 35px;
text-transform: uppercase;
font-size: 15px;
}
&.active,
&:hover {
.nav-link {
background-color: $primary1;
color: $white;
}
}
}
}
}
a,
a:hover,
a:focus {
text-decoration: none;
}
a:hover,
a:focus {
color: initial;
}
.btn,
.btn:focus {
outline: none !important;
box-shadow: none;
}
.custom_nav-container .nav_search-btn {
background-image: url(../images/search-icon.png);
background-size: 22px;
background-repeat: no-repeat;
background-position-y: 7px;
width: 35px;
height: 35px;
padding: 0;
border: none;
}
.navbar-brand {
display: flex;
align-items: center;
img {
margin-right: 5px;
width: 70px;
height: 70px;
}
span {
font-size: 22px;
font-weight: 700;
color: $primary1;
}
}
.custom_nav-container {
z-index: 99999;
}
.navbar-expand-lg .navbar-collapse {
align-items: flex-end; //for this site only
}
.custom_nav-container .navbar-toggler {
outline: none;
}
.custom_nav-container .navbar-toggler {
padding: 0;
width: 37px;
height: 42px;
span {
display: block;
width: 35px;
height: 4px;
background-color: #190734;
margin: 7px 0;
transition: all .3s;
}
&[aria-expanded="true"] {
.s-1 {
transform: rotate(45deg);
margin: 0;
margin-bottom: -4px;
}
.s-2 {
display: none;
}
.s-3 {
transform: rotate(-45deg);
margin: 0;
margin-top: -4px;
}
}
&[aria-expanded="false"] {
.s-1,
.s-2,
.s-3 {
transform: none;
}
}
}
/*end header section*/
/* slider section */
.slider_section {
flex: 1;
display: flex;
align-items: center;
position: relative;
z-index: 2;
color: #3b3a3a;
padding-bottom: 90px;
.row {
align-items: center;
}
.detail_box {
color: $black;
h1 {
text-transform: uppercase;
font-weight: bold;
}
p {
margin-top: 20px;
}
a {
@include hero_btn($primary1, $white, 10px, 40px, 35px);
margin-top: 35px;
}
}
.img_container {
border: 7px solid #7b57b2;
border-radius: 100%;
overflow: hidden;
div#carouselExampleContarols {
width: 100%;
position: unset;
}
.img-box {
img {
width: 100%;
}
}
}
.carousel-control-prev,
.carousel-control-next {
top: initial;
left: initial;
bottom: 5%;
right: 10%;
width: 45px;
height: 45px;
border: none;
border-radius: 100%;
opacity: 1;
background-repeat: no-repeat;
background-size: 8px;
background-position: center;
}
.carousel-control-prev {
background-image: url(../images/prev.png);
background-color: $white;
transform: translate(-85px, 30px);
}
.carousel-control-next {
background-image: url(../images/next.png);
background-color: $primary1;
transform: translate(-45px, 0);
}
}
// end slider section
// service section
.service_section {
text-align: center;
.heading_container {
justify-content: center;
}
.service_container {
display: flex;
justify-content: center;
padding: 35px 0;
flex-wrap: wrap;
.box {
margin: 25px 1%;
flex-basis: 31%;
padding: 35px 25px 25px;
border-radius: 15px;
box-shadow: 0 0 10px 0 rgba($color: #000000, $alpha: .15);
border-top: 15px solid transparent;
overflow: hidden;
transition: all .1s;
.img-box {
display: flex;
justify-content: center;
align-items: center;
height: 125px;
img {
width: 90px;
}
}
.detail-box {
margin-top: 25px;
h5 {
color: #2e0e5f;
font-weight: 600;
position: relative;
}
}
&:hover,
&.active {
border-top: 15px solid #512a97;
}
}
}
.btn-box {
display: flex;
justify-content: center;
margin-top: 25px;
a {
@include hero_btn($primary1, $white, 10px, 35px, 35px);
}
}
}
// end service section
// about section
.about_section {
background-color: #f3f0f6;
.row {
align-items: center;
}
.img_container {
display: flex;
flex-direction: column;
.img-box {
border: 5px solid #7b57b2;
border-radius: 100%;
overflow: hidden;
&.b1 {
width: 70%;
}
&.b2 {
width: 50%;
margin-left: auto;
margin-top: -12%;
}
img {
width: 100%;
}
}
}
.detail-box {
margin-right: 15%;
p {
margin-top: 25px;
}
a {
@include hero_btn($primary1, $white, 10px, 35px, 5px);
margin: 25px 0 45px 0;
}
}
}
// end about section
// blog section
.blog_section {
.heading_container {
justify-content: center;
h2 {
&::before {
background-color: $white;
}
}
}
.box {
margin-top: 55px;
background-color: $white;
box-shadow: 0 0 10px 0 rgba($color: #000000, $alpha: .15);
.img-box {
position: relative;
img {
width: 100%;
}
}
.detail-box {
padding: 25px 25px 15px;
h5 {
font-weight: bold;
}
}
}
}
// end blog section
// contact section
.contact_section {
position: relative;
form {
margin-top: 45px;
padding-right: 35px;
}
input {
width: 100%;
border: none;
height: 50px;
margin-bottom: 25px;
padding-left: 25px;
background-color: transparent;
outline: none;
color: #101010;
-webkit-box-shadow: 0px 2px 5px 0px rgba(0, 0, 0, 0.16);
-moz-box-shadow: 0px 2px 5px 0px rgba(0, 0, 0, 0.16);
box-shadow: 0px 2px 5px 0px rgba(0, 0, 0, 0.16);
&::placeholder {
color: #737272;
}
&.message-box {
height: 120px;
}
}
button {
border: none;
@include hero_btn($primary1, $white, 12px, 45px, 0px);
margin-top: 35px;
}
.map_container {
height: 100%;
min-height: 325px;
.map-responsive {
height: 100%;
}
}
}
// end contact section
.footer_bg {
background-image: url(../images/footer-bg.png);
background-size: cover;
background-position: top;
}
/* info section */
.info_section {
background-color: #190734;
color: $white;
h6 {
font-weight: bold;
}
.info_contact {
margin-top: 60px;
margin-bottom: 45px;
.col-md-4 {
display: flex;
justify-content: center;
}
a {
color: $white;
}
img {
max-width: 100%;
margin-right: 10px;
}
}
.info_form {
margin: 0 auto;
margin-bottom: 45px;
h4 {
text-transform: uppercase;
text-align: center;
margin-bottom: 20px;
}
form {
display: flex;
align-items: center;
input {
background-color: $white;
border: none;
flex: 2.5;
outline: none;
color: $black;
min-height: 42.4px;
padding-left: 15px;
::placeholder {
color: $white;
opacity: 0.2;
}
}
button {
flex: 1;
border: none;
@include hero_btn($primary1, $white, 10px, 30px, 0);
font-size: 15px;
text-transform: uppercase;
}
}
}
.box {
display: flex;
}
.info_social {
display: flex;
img {
width: 35px;
margin-right: 8px;
}
}
}
/* end info section */
/* footer section*/
.footer_section {
display: flex;
justify-content: center;
position: relative;
}
.footer_section p {
color: #222222;
margin: 0 auto;
text-align: center;
padding: 20px;
a {
color: #222222;
}
}
// end footer section

View File

@ -0,0 +1,2 @@
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:

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 188 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 76 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 72 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 74 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 515 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 619 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 691 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 805 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 665 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 433 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 204 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 700 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 182 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 111 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 58 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 139 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 110 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 430 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 681 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@ -1,29 +0,0 @@
Kunststil und Techniken: Kirsten Klöckner ist eine Künstlerin, die sich auf Aquarell- und Tusche-Materialien spezialisiert hat. Diese Techniken erfordern ein hohes Maß an Geschick und Präzision, da sie sowohl transparente als auch deckende Effekte erzeugen kann. Die Verwendung von Papier als Untergrund ermöglicht es ihr, mit verschiedenen Strukturen und Texturen zu experimentieren. Die Vielfalt der Techniken, die sie beherrscht - wie Federzeichnung, Pinselzeichnung, Nass-in-Nass-Technik, Trocken-auf-Trocken-Technik und Lasur - ermöglicht es ihr, ihre künstlerische Vision in unterschiedlichen Ausdrucksformen zu realisieren.
Themen und Motive: Klöckners Kunst zeigt eine breite Palette von Themen und Motiven. Ihre Werke enthalten oft Naturmotive. Gleichzeitig widmet sie sich aber auch gesellschaftlichen und politischen Anliegen, wie zum Beispiel Gastfreundschaft, Verantwortung, Klimaschutz und kritischen Reflektionen über den Alltag. Die Vielfalt der Themen zeigt, dass sie eine Künstlerin ist, die sich für viele Facetten des Lebens interessiert und ihre Kunst als Ausdrucksmittel für verschiedene Gedanken und Gefühle nutzt. Oftmals werden die Kernobjekte eines Werkes sehr detailliert dargestellt und etwas weniger abstrakt.
Emotionen und Interpretation: Kirsten Klöckners Kunst scheint stark von Emotionen durchdrungen zu sein, die bei den Betrachtern Resonanz erzeugen. Die Assoziationen und Reaktionen anderer Menschen auf ihre Werke reichen von Freude und Dankbarkeit bis hin zu nachdenklichen Reflexionen über gesellschaftliche Fragen. Dies deutet darauf hin, dass ihre Kunst eine breite Palette von Emotionen anspricht und eine starke Verbindung zu den Betrachtern herstellt. Klöckners Fähigkeit, Emotionen in ihren Werken zu vermitteln, zeugt von ihrer künstlerischen Sensibilität und ihrer Fähigkeit, eine tiefere Ebene der Kommunikation mit ihrem Publikum zu erreichen.
Narrative Elemente: In ihrer Kunst integriert Klöckner oft narrative Elemente, die Geschichten erzählen oder eine tiefere Bedeutung hervorheben. Diese erzählerischen Aspekte tragen dazu bei, dass ihre Werke komplexer und aussagekräftiger werden. Die Verwendung von Symbolen wie Schleifen, Tischen und Haken in ihren Bildern gibt den Betrachtern einen zusätzlichen Anreiz, die Bedeutung hinter den Kunstwerken zu erkunden und sich mit den dargestellten Themen auseinanderzusetzen. Sie teilt die Titel ihrer Werke oft in einzelne Worte welche dann als jeweiliges Element Einzug in ihre Werke finden. (z.B. Schilderwald wird zu einem Bild aus Schildern in einem Wald).
Künstlerische Ambition und Botschaft: Kirsten Klöckner zeigt durch ihre Kunst eine klare Botschaft und Ambition. Ihre Werke sind nicht nur ästhetisch ansprechend, sondern dienen auch als Medium, um ihre persönlichen Überzeugungen und Gedanken zu verschiedenen Themen auszudrücken. Sie fordert die Betrachter dazu auf, über gesellschaftliche Fragen, Naturverbundenheit und das menschliche Dasein nachzudenken. Ihre Kunst regt Diskussionen und Reflexionen an und zeigt, dass sie als Künstlerin eine Botschafterin für verschiedenste Anliegen ist.
Dies die Vorgehensweise bei der Entwicklung eines Bildes von Kirsten Klöckner.
Wenn sie einen Titel bekommen hat und dazu ein Bild malen sollte, hat sie so gearbeitet. Bitte generiere einen Englischen Prompt für eine Bild KI basierend auf den gennanten Aspekten.
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

@ -1,16 +1,10 @@
Du wirst gleich einen Titel f<>r ein Bild bekommen. Bitte versuch diesen Titel in eine Bildidee f<>r eine KI umzuwandeln. Bitte generiere einen Englischen Prompt f<>r dieses Bild
Hier sind Ideen, wie du den Titel umformen kannst:
"Interpretieren Sie den Titel tiefsinnig und mehrschichtig, finden Sie Symbole und tiefere Bedeutungen. Nutzen Sie pers<72>nliche oder gesellschaftliche Filter f<>r die Interpretation. Bringen Sie abstrakte Darstellungen, Symbole und Metaphern ein, die der Titel hervorruft. Bedenken Sie gesellschaftliche und kulturelle Themen sowie Themen wie Toleranz und Verantwortung. F<>gen Sie Humor und Ironie hinzu, hinterfragen Sie traditionelle Themen kritisch. Reflektieren Sie Ihre Emotionen und Gedanken, stellen Sie sicher, dass Ihr Kunstwerk eine Aussage trifft. Lassen Sie Interpretation und Assoziationen zu, erforschen Sie neue Kontexte, seien Sie offen f<>r <20>berraschungen und hinterfragen Sie das Gewohnte."
Bitte generiere einen Englischen Prompt f<>r eine Bild KI basierend auf diesen vorherigen Herangehensweisen.
Hier findest du Beispiele, wie der Promt aussehen soll: Hier findest du Beispiele, wie der Promt aussehen soll:
"Portrait of an astronaut in space, detailed starry background, reflective helmet." "Painting of an astronaut in space, detailed starry background, reflective helmet."
<EFBFBD>Painting of a floating island with giant clock gears, populated with mythical creatures.<2E> <EFBFBD>Painting of a floating island with giant clock gears, populated with mythical creatures.<2E>
<EFBFBD>Landscape of a Japanese garden in autumn, with a bridge over a koi pond.<2E> <EFBFBD>Painting of a Japanese garden in autumn, with a bridge over a koi pond.<2E>
<EFBFBD>Painting representing the sound of jazz music, using pale colors and erratic shapes.<2E> <EFBFBD>Painting representing the sound of jazz music, using pale colors and erratic shapes.<2E>
Bitte nutze unbedingt f<>r den Prompt maximal 20 W<>rter!
Der Promt selber darf auf keinen Fall abstrakt sein, man muss durch den Promt ein genaues Bild vor Augen haben.
Der Titel lautet: 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

@ -0,0 +1,24 @@
<?xml version="1.0" encoding="utf-8"?>
<Operations Version="1.0" xmlns="http://schemas.microsoft.com/sqlserver/dac/Serialization/2012/02">
<Operation Name="Rename Refactor" Key="c957123b-8f1b-4753-96eb-c2ea2811027a" ChangeDateTime="10/10/2023 12:47:37">
<Property Name="ElementName" Value="[dbo].[BildInfo].[Prompt]" />
<Property Name="ElementType" Value="SqlSimpleColumn" />
<Property Name="ParentElementName" Value="[dbo].[BildInfo]" />
<Property Name="ParentElementType" Value="SqlTable" />
<Property Name="NewName" Value="BildPrompt" />
</Operation>
<Operation Name="Rename Refactor" Key="9e69babc-e66c-496f-960a-0c9ad936d763" ChangeDateTime="10/10/2023 12:47:42">
<Property Name="ElementName" Value="[dbo].[BildInfo].[Beschreibung]" />
<Property Name="ElementType" Value="SqlSimpleColumn" />
<Property Name="ParentElementName" Value="[dbo].[BildInfo]" />
<Property Name="ParentElementType" Value="SqlTable" />
<Property Name="NewName" Value="BildBeschreibung" />
</Operation>
<Operation Name="Rename Refactor" Key="1dc11132-1619-4a0d-b261-0d56392a3d51" ChangeDateTime="10/10/2023 13:39:00">
<Property Name="ElementName" Value="[dbo].[BildInfo].[Index]" />
<Property Name="ElementType" Value="SqlSimpleColumn" />
<Property Name="ParentElementName" Value="[dbo].[BildInfo]" />
<Property Name="ParentElementType" Value="SqlTable" />
<Property Name="NewName" Value="GroupIndex" />
</Operation>
</Operations>

View File

@ -0,0 +1,81 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<Name>KiKunstDatenbank</Name>
<SchemaVersion>2.0</SchemaVersion>
<ProjectVersion>4.1</ProjectVersion>
<ProjectGuid>{a19cd19a-fe5b-4d4e-896b-dcc43b45f734}</ProjectGuid>
<DSP>Microsoft.Data.Tools.Schema.Sql.Sql150DatabaseSchemaProvider</DSP>
<OutputType>Database</OutputType>
<RootPath>
</RootPath>
<RootNamespace>KiKunstDatenbank</RootNamespace>
<AssemblyName>KiKunstDatenbank</AssemblyName>
<ModelCollation>1033, CI</ModelCollation>
<DefaultFileStructure>BySchemaAndSchemaType</DefaultFileStructure>
<DeployToDatabase>True</DeployToDatabase>
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
<TargetLanguage>CS</TargetLanguage>
<AppDesignerFolder>Properties</AppDesignerFolder>
<SqlServerVerification>False</SqlServerVerification>
<IncludeCompositeObjects>True</IncludeCompositeObjects>
<TargetDatabaseSet>True</TargetDatabaseSet>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<OutputPath>bin\Release\</OutputPath>
<BuildScriptName>$(MSBuildProjectName).sql</BuildScriptName>
<TreatWarningsAsErrors>False</TreatWarningsAsErrors>
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<DefineDebug>false</DefineDebug>
<DefineTrace>true</DefineTrace>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<OutputPath>bin\Debug\</OutputPath>
<BuildScriptName>$(MSBuildProjectName).sql</BuildScriptName>
<TreatWarningsAsErrors>false</TreatWarningsAsErrors>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<DefineDebug>true</DefineDebug>
<DefineTrace>true</DefineTrace>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup>
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">11.0</VisualStudioVersion>
<!-- Default to the v11.0 targets path if the targets file for the current VS version is not found -->
<SSDTExists Condition="Exists('$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v$(VisualStudioVersion)\SSDT\Microsoft.Data.Tools.Schema.SqlTasks.targets')">True</SSDTExists>
<VisualStudioVersion Condition="'$(SSDTExists)' == ''">11.0</VisualStudioVersion>
</PropertyGroup>
<Import Condition="'$(SQLDBExtensionsRefPath)' != ''" Project="$(SQLDBExtensionsRefPath)\Microsoft.Data.Tools.Schema.SqlTasks.targets" />
<Import Condition="'$(SQLDBExtensionsRefPath)' == ''" Project="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v$(VisualStudioVersion)\SSDT\Microsoft.Data.Tools.Schema.SqlTasks.targets" />
<ItemGroup>
<Folder Include="Properties" />
<Folder Include="dpo" />
<Folder Include="dpo\Tables" />
<Folder Include="dpo\StoredProcedures" />
</ItemGroup>
<ItemGroup>
<Build Include="dpo\Tables\BildInfo.sql" />
<Build Include="dpo\StoredProcedures\spBildInfo_Insert.sql" />
<Build Include="dpo\Tables\WunschInfo.sql" />
<Build Include="dpo\StoredProcedures\spWunschInfo_Insert.sql" />
<Build Include="dpo\StoredProcedures\spBildInfo_UpdateFileName.sql" />
<Build Include="dpo\StoredProcedures\spBildInfo_GetAll.sql" />
<Build Include="dpo\StoredProcedures\spWunschInfo_Get.sql" />
</ItemGroup>
<ItemGroup>
<RefactorLog Include="KiKunstDatenbank.refactorlog" />
</ItemGroup>
<ItemGroup>
<PostDeploy Include="Script.PostDeployment.sql" />
</ItemGroup>
<ItemGroup>
<None Include="KiKunstDatenbank.publish.xml" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,19 @@
/*
Vorlage für ein Skript nach der Bereitstellung
--------------------------------------------------------------------------------------
Diese Datei enthält SQL-Anweisungen, die an das Buildskript angefügt werden.
Schließen Sie mit der SQLCMD-Syntax eine Datei in das Skript nach der Bereitstellung ein.
Beispiel: :r .\myfile.sql
Verwenden Sie die SQLCMD-Syntax, um auf eine Variable im Skript nach der Bereitstellung zu verweisen.
Beispiel: :setvar TableName MyTable
SELECT * FROM [$(TableName)]
--------------------------------------------------------------------------------------
*/
--IF NOT EXISTS (SELECT 1 FROM [dbo].[User])
--BEGIN
-- INSERT INTO [dbo].[User] (FirstName, LastName)
-- VALUES ('Simon', 'Lübeß'),
-- ('Peter', 'Enis'),
-- ('John', 'Smith'),
-- ('Mary', 'Jones')
--END

View File

@ -0,0 +1,6 @@
CREATE PROCEDURE [dbo].[spBildInfo_GetAll]
AS
BEGIN
SELECT Id, Datum, Dateiname, ImageModel, WunschId
FROM [dbo].[BildInfo];
END

View File

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

View File

@ -0,0 +1,9 @@
CREATE PROCEDURE [dbo].[spBildInfo_UpdateFileName]
@Id INT,
@Dateiname NCHAR(256)
AS
BEGIN
UPDATE [dbo].[BildInfo]
SET Dateiname = @Dateiname
WHERE Id = @Id;
END

View File

@ -0,0 +1,8 @@
CREATE PROCEDURE [dbo].[spWunschInfo_Get]
@Id INT
AS
BEGIN
SELECT Id, Wunsch, BildPrompt, BildBeschreibung, Datum, GPTModel
FROM [dbo].[WunschInfo]
WHERE Id = @Id;
END

View File

@ -0,0 +1,18 @@
CREATE PROCEDURE [dbo].[spWunschInfo_Insert]
@Id INT,
@Wunsch NVARCHAR(1024),
@BildPrompt NVARCHAR(MAX),
@BildBeschreibung NVARCHAR(MAX),
@Datum DATETIME2,
@GPTModel NCHAR(32)
AS
BEGIN
INSERT INTO [dbo].[WunschInfo] (Wunsch, BildPrompt, BildBeschreibung, Datum, GPTModel)
VALUES (@Wunsch,
@BildPrompt,
@BildBeschreibung,
@Datum,
@GPTModel);
SELECT Id FROM [dbo].[WunschInfo] WHERE Id = CAST(SCOPE_IDENTITY() AS INT);
END

View File

@ -0,0 +1,8 @@
CREATE TABLE [dbo].[BildInfo]
(
[Id] INT NOT NULL PRIMARY KEY IDENTITY,
[Datum] DATETIME2 NOT NULL,
[Dateiname] NCHAR(256) NOT NULL,
[ImageModel] NCHAR(32) NOT NULL,
[WunschId] INT NOT NULL
)

View File

@ -0,0 +1,9 @@
CREATE TABLE [dbo].[WunschInfo]
(
[Id] INT NOT NULL PRIMARY KEY IDENTITY,
[Wunsch] NVARCHAR (1024) NOT NULL,
[BildPrompt] NVARCHAR (MAX) NOT NULL,
[BildBeschreibung] NVARCHAR (MAX) NOT NULL,
[Datum] DATETIME2 (7) NOT NULL,
[GPTModel] NCHAR (32) NOT NULL
)