diff --git a/Assemblies/AIImages.dll b/Assemblies/AIImages.dll index 26489bc..9b40a6c 100644 Binary files a/Assemblies/AIImages.dll and b/Assemblies/AIImages.dll differ diff --git a/Languages/English/Keyed/AIImages.xml b/Languages/English/Keyed/AIImages.xml index 4a1b8ce..2c8fdbf 100644 --- a/Languages/English/Keyed/AIImages.xml +++ b/Languages/English/Keyed/AIImages.xml @@ -61,6 +61,10 @@ Image saved to: {0} Loaded saved portrait No image generated yet.\nClick "Generate Image" to start. + + Image Type + Portrait + Full Body API Settings Configure connection to Stable Diffusion API diff --git a/Languages/Russian/Keyed/AIImages.xml b/Languages/Russian/Keyed/AIImages.xml index 2a0422a..c5dd326 100644 --- a/Languages/Russian/Keyed/AIImages.xml +++ b/Languages/Russian/Keyed/AIImages.xml @@ -61,6 +61,10 @@ Изображение сохранено в: {0} Загружен сохраненный портрет Изображение еще не сгенерировано.\nНажмите "Сгенерировать изображение" для начала. + + Тип изображения + Портрет + Полное тело Настройки API Настройка подключения к API Stable Diffusion diff --git a/Source/AIImages/Models/StableDiffusionSettings.cs b/Source/AIImages/Models/StableDiffusionSettings.cs index f472b29..859ad1a 100644 --- a/Source/AIImages/Models/StableDiffusionSettings.cs +++ b/Source/AIImages/Models/StableDiffusionSettings.cs @@ -1,5 +1,14 @@ namespace AIImages.Models { + /// + /// Тип генерации изображения + /// + public enum ImageType + { + Portrait, // Портрет + FullBody, // Полное тело + } + /// /// Настройки для генерации изображений через Stable Diffusion /// @@ -16,6 +25,7 @@ namespace AIImages.Models public int Seed { get; set; } public string Model { get; set; } public string ArtStyleDefName { get; set; } + public ImageType ImageType { get; set; } public StableDiffusionSettings() { @@ -30,6 +40,7 @@ namespace AIImages.Models ArtStyleDefName = "ArtStyle_Realistic"; PositivePrompt = ""; NegativePrompt = "ugly, deformed, low quality, blurry, bad anatomy, worst quality"; + ImageType = ImageType.Portrait; } } } diff --git a/Source/AIImages/Services/AdvancedPromptGenerator.cs b/Source/AIImages/Services/AdvancedPromptGenerator.cs index d519026..342974d 100644 --- a/Source/AIImages/Services/AdvancedPromptGenerator.cs +++ b/Source/AIImages/Services/AdvancedPromptGenerator.cs @@ -59,8 +59,10 @@ namespace AIImages.Services prompt.Append(", "); } - // 3. Тип кадра - prompt.Append("portrait, "); + // 3. Тип кадра (portrait или full body) + string frameType = + settings.ImageType == Models.ImageType.FullBody ? "full body, " : "portrait, "; + prompt.Append(frameType); // 4. Пол персонажа (в формате anime/SD теги) string genderTag = appearanceData.Gender == Gender.Female ? "1girl" : "1boy"; diff --git a/Source/AIImages/Settings/AIImagesModSettings.cs b/Source/AIImages/Settings/AIImagesModSettings.cs index 9a663e0..756de16 100644 --- a/Source/AIImages/Settings/AIImagesModSettings.cs +++ b/Source/AIImages/Settings/AIImagesModSettings.cs @@ -44,6 +44,9 @@ namespace AIImages.Settings // Путь для сохранения public string savePath = "AIImages/Generated"; + // Тип генерации + public AIImages.Models.ImageType imageType = AIImages.Models.ImageType.Portrait; + // Флаги public bool autoLoadModels = true; public bool showTechnicalInfo = true; @@ -75,6 +78,8 @@ namespace AIImages.Settings Scribe_Values.Look(ref savePath, "savePath", "AIImages/Generated"); + Scribe_Values.Look(ref imageType, "imageType", AIImages.Models.ImageType.Portrait); + Scribe_Values.Look(ref autoLoadModels, "autoLoadModels", true); Scribe_Values.Look(ref showTechnicalInfo, "showTechnicalInfo", true); Scribe_Values.Look(ref saveGenerationHistory, "saveGenerationHistory", true); @@ -102,6 +107,7 @@ namespace AIImages.Settings ArtStyleDefName = artStyleDefName, PositivePrompt = basePositivePrompt, NegativePrompt = baseNegativePrompt, + ImageType = imageType, }; } } diff --git a/Source/AIImages/Window_AIImage.cs b/Source/AIImages/Window_AIImage.cs index 293c55c..2e8cce9 100644 --- a/Source/AIImages/Window_AIImage.cs +++ b/Source/AIImages/Window_AIImage.cs @@ -793,6 +793,7 @@ namespace AIImages { float curY = rect.y; + curY = DrawImageTypeSelector(rect, curY); curY = DrawImagePreview(rect, curY); curY = DrawGenerationStatus(rect, curY); curY = DrawProgressBar(rect, curY); @@ -1146,6 +1147,75 @@ namespace AIImages return curY; } + /// + /// Отрисовывает селектор типа изображения (портрет/полное тело) + /// + private float DrawImageTypeSelector(Rect rect, float curY) + { + Text.Font = GameFont.Small; + float selectorHeight = 30f; + + // Заголовок + Widgets.Label( + new Rect(rect.x, curY, rect.width * 0.4f, selectorHeight), + "AIImages.ImageType.Label".Translate() + ":" + ); + + // Радио-кнопки для выбора типа + float radioX = rect.x + rect.width * 0.45f; + float radioWidth = rect.width * 0.25f; + float radioSpacing = 5f; + + // Портрет + Rect portraitRect = new Rect(radioX, curY + 2f, radioWidth, selectorHeight - 4f); + bool isPortrait = generationSettings.ImageType == Models.ImageType.Portrait; + if ( + Widgets.RadioButtonLabeled( + portraitRect, + "AIImages.ImageType.Portrait".Translate(), + isPortrait + ) && !isPortrait + ) + { + generationSettings.ImageType = Models.ImageType.Portrait; + // Обновляем настройки в глобальных настройках + AIImagesMod.Settings.imageType = Models.ImageType.Portrait; + // При смене на портрет, можно изменить размеры на более квадратные + if (generationSettings.Width > generationSettings.Height) + { + generationSettings.Height = generationSettings.Width; + } + } + + // Полное тело + Rect fullBodyRect = new Rect( + radioX + radioWidth + radioSpacing, + curY + 2f, + radioWidth, + selectorHeight - 4f + ); + bool isFullBody = generationSettings.ImageType == Models.ImageType.FullBody; + if ( + Widgets.RadioButtonLabeled( + fullBodyRect, + "AIImages.ImageType.FullBody".Translate(), + isFullBody + ) && !isFullBody + ) + { + generationSettings.ImageType = Models.ImageType.FullBody; + // Обновляем настройки в глобальных настройках + AIImagesMod.Settings.imageType = Models.ImageType.FullBody; + // При смене на полное тело, можно увеличить высоту + if (generationSettings.Width >= generationSettings.Height) + { + generationSettings.Height = (int)(generationSettings.Width * 1.5f); + } + } + + return curY + selectorHeight + 10f; + } + private float DrawImagePreview(Rect rect, float curY) { if (generatedImage != null)