diff --git a/README.md b/README.md index 5b4d2e4..98744f9 100644 --- a/README.md +++ b/README.md @@ -73,6 +73,11 @@ see [Documents](https://github.com/Invary/IvyPhotoshopDiffusion/tree/main/doc) p ## Changelog +- Ver102
+Support text2image. Use generate button with pressing [shift] key
+Change log output of generated images to InfoText only
+ + - Ver101
Bug fix log message out
Bug fix seed input
diff --git a/src/IvyPhotoshopDiffusion/Automatic1111.cs b/src/IvyPhotoshopDiffusion/Automatic1111.cs index a39ff8f..e1a4e8c 100644 --- a/src/IvyPhotoshopDiffusion/Automatic1111.cs +++ b/src/IvyPhotoshopDiffusion/Automatic1111.cs @@ -11,13 +11,74 @@ namespace Invary.IvyPhotoshopDiffusion { + + // api documents + // request json is ducumented, but response is undocumented (2022/10/30) + // http://127.0.0.1:7860/docs#/default/img2imgapi_sdapi_v1_img2img_post + // https://github.com/AUTOMATIC1111/stable-diffusion-webui/wiki/API + + + internal class Automatic1111 { + public static JsonResponseBase Send(JsonRequestBase request) + { + if (request.GetType() == typeof(JsonRequestImg2Img)) + { + var reqImg2Img = request as JsonRequestImg2Img; + return SendImg2Img(reqImg2Img); + } + + if (request.GetType() == typeof(JsonRequestTxt2Img)) + { + var reqTxt2Img = request as JsonRequestTxt2Img; + return SendTxt2Img(reqTxt2Img); + } + + return null; + } + + + public static JsonResponseTxt2Img SendTxt2Img(JsonRequestTxt2Img objJson) + { + string jsonString = JsonSerializer.Serialize(objJson); + + var url = $"{XmlSetting.Current.Automatic1111ApiUrl}/sdapi/v1/txt2img"; + + var request = WebRequest.Create(url); + request.Method = "POST"; + + string json = jsonString; + byte[] byteArray = Encoding.UTF8.GetBytes(json); + + request.ContentType = "application/json"; + request.ContentLength = byteArray.Length; + + using (var reqStream = request.GetRequestStream()) + { + reqStream.Write(byteArray, 0, byteArray.Length); + + using (var response = request.GetResponse()) + { + Debug.WriteLine(((HttpWebResponse)response).StatusDescription); + + using (var respStream = response.GetResponseStream()) + using (var reader = new StreamReader(respStream)) + { + + string jsonresponse = reader.ReadToEnd(); + //Debug.WriteLine(data); + + return JsonSerializer.Deserialize(jsonresponse); + } + } + } + } - public static JsonResponseImg2Img Send(JsonRequestImg2Img objJson) + public static JsonResponseImg2Img SendImg2Img(JsonRequestImg2Img objJson) { string jsonString = JsonSerializer.Serialize(objJson); @@ -92,167 +153,112 @@ public static bool SaveBase64EncodingData(string file, string text) - - - - - - public class JsonRequestTxt2Img + public class JsonRequestBase { - //public object sd_model { get; set; } = null; - //public string outpath_samples { get; set; } - //public string outpath_grids { get; set; } - //public string prompt_for_display { get; set; } public string prompt { get; set; } = ""; - public string negative_prompt { get; set; } = ""; - //public string[] styles { get; set; } + + public string[] styles { get; set; } + public float denoising_strength { get; set; } = 0.75f; + public decimal seed { get; set; } = -1; - //public float subseed_strength { get; set; } = 0.0f; - //public decimal subseed { get; set; } = -1; - //public int seed_resize_from_h { get; set; } - //public int seed_resize_from_w { get; set; } - public string sampler_index { get; set; } = "Euler"; + public decimal subseed { get; set; } = -1; + public float subseed_strength { get; set; } = 0.0f; + public int seed_resize_from_h { get; set; } = -1; + public int seed_resize_from_w { get; set; } = -1; + public int batch_size { get; set; } = 1; public int n_iter { get; set; } = 1; public int steps { get; set; } = 20; public float cfg_scale { get; set; } = 7.0f; public int width { get; set; } = 512; public int height { get; set; } = 512; - public int restore_faces { get; set; } = 0; - public int tiling { get; set; } = 0; - //public int do_not_save_samples { get; set; } - //public int do_not_save_grid { get; set; } - - //public int inpainting_fill { get; set; } - //public bool inpaint_full_res { get; set; } - //public int inpaint_full_res_padding { get; set; } - public int inpainting_mask_invert { get; set; } = 0; - } - public class JsonRequestImg2Img : JsonRequestTxt2Img - { - public string[] init_images { get; set; } - public string mask { get; set; } - public float denoising_strength { get; set; } = 0.75f; - public int mask_blur { get; set; } = 4; - } + public bool restore_faces { set; get; } = false; + public bool tiling { set; get; } = false; + public string negative_prompt { get; set; } = ""; + + public int eta { get; set; } = 0; + + public int s_churn { get; set; } = 0; + public int s_tmax { get; set; } = 0; + public int s_tmin { get; set; } = 0; + public int s_noise { get; set; } = 1; + public Override_Settings override_settings { get; set; } + public string sampler_index { get; set; } = "Euler"; + + } - public class JsonResponseTxt2Img + + public class Override_Settings { - public string[] images { get; set; } - public Parameters parameters { get; set; } - public string info { get; set; } } - public class Parameters + + + + public class JsonRequestTxt2Img : JsonRequestBase { - public bool enable_hr { get; set; } - public int denoising_strength { get; set; } - public int firstphase_width { get; set; } - public int firstphase_height { get; set; } - public string prompt { get; set; } - public object styles { get; set; } - public decimal seed { get; set; } - public decimal subseed { get; set; } - public int subseed_strength { get; set; } - public int seed_resize_from_h { get; set; } - public int seed_resize_from_w { get; set; } - public int batch_size { get; set; } - public int n_iter { get; set; } - public int steps { get; set; } - public float cfg_scale { get; set; } - public int width { get; set; } - public int height { get; set; } - public bool restore_faces { get; set; } - public bool tiling { get; set; } - public string negative_prompt { get; set; } - public object eta { get; set; } - public float s_churn { get; set; } - public object s_tmax { get; set; } - public float s_tmin { get; set; } - public float s_noise { get; set; } - public string sampler_index { get; set; } + public bool enable_hr { set; get; } = false; + public int firstphase_width { get; set; } = 0; + public int firstphase_height { get; set; } = 0; + } + public class JsonRequestImg2Img : JsonRequestBase + { + public string[] init_images { get; set; } + public int resize_mode { get; set; } = 0; - //public class JsonResponseImg2Img - //{ - // public string[] images { get; set; } - // public ParametersResponseImg2Img parameters { get; set; } - // public string info { get; set; } - //} - //public class ParametersResponseImg2Img - //{ - // public string[] init_images { get; set; } - // public int resize_mode { get; set; } - // public float denoising_strength { get; set; } - // public object mask { get; set; } - // public int mask_blur { get; set; } - // public int inpainting_fill { get; set; } - // public bool inpaint_full_res { get; set; } - // public int inpaint_full_res_padding { get; set; } - // public int inpainting_mask_invert { get; set; } - // public string prompt { get; set; } - // public object styles { get; set; } - // public decimal seed { get; set; } - // public decimal subseed { get; set; } - // public int subseed_strength { get; set; } - // public int seed_resize_from_h { get; set; } - // public int seed_resize_from_w { get; set; } - // public int batch_size { get; set; } - // public int n_iter { get; set; } - // public int steps { get; set; } - // public float cfg_scale { get; set; } - // public int width { get; set; } - // public int height { get; set; } - // public bool restore_faces { get; set; } - // public bool tiling { get; set; } - // public string negative_prompt { get; set; } - // public object eta { get; set; } - // public float s_churn { get; set; } - // public object s_tmax { get; set; } - // public float s_tmin { get; set; } - // public float s_noise { get; set; } - // public string sampler_index { get; set; } - //} + public string mask { get; set; } + public int mask_blur { get; set; } = 4; + public int inpainting_fill { get; set; } = 0; + public bool inpaint_full_res { get; set; } = false; + public int inpaint_full_res_padding { get; set; } = 0; + public int inpainting_mask_invert { get; set; } = 0; + public bool include_init_images { get; set; } = false; + } + - public class JsonResponseImg2Img + + public class JsonResponseBase { public string[] images { get; set; } - public ParametersResponseImg2Img parameters { get; set; } public Info info { get; set; } } - public class ParametersResponseImg2Img + + + public class JsonResponseTxt2Img : JsonResponseBase + { + public ParametersTxt2Img parameters { get; set; } + } + + + + + public class ParametersBase { - public object init_images { get; set; } - public int resize_mode { get; set; } public float denoising_strength { get; set; } - public object mask { get; set; } - public int mask_blur { get; set; } - public int inpainting_fill { get; set; } - public bool inpaint_full_res { get; set; } - public int inpaint_full_res_padding { get; set; } - public int inpainting_mask_invert { get; set; } + public string prompt { get; set; } public object styles { get; set; } public decimal seed { get; set; } public decimal subseed { get; set; } - public int subseed_strength { get; set; } + public float subseed_strength { get; set; } public int seed_resize_from_h { get; set; } public int seed_resize_from_w { get; set; } public int batch_size { get; set; } @@ -261,6 +267,7 @@ public class ParametersResponseImg2Img public float cfg_scale { get; set; } public int width { get; set; } public int height { get; set; } + public bool restore_faces { get; set; } public bool tiling { get; set; } public string negative_prompt { get; set; } @@ -271,9 +278,18 @@ public class ParametersResponseImg2Img public float s_noise { get; set; } public object override_settings { get; set; } public string sampler_index { get; set; } - public bool include_init_images { get; set; } } + + + public class ParametersTxt2Img : ParametersBase + { + public bool enable_hr { get; set; } + public int firstphase_width { get; set; } + public int firstphase_height { get; set; } + } + + public class Info { public string prompt { get; set; } @@ -283,7 +299,7 @@ public class Info public decimal[] all_seeds { get; set; } public decimal subseed { get; set; } public decimal[] all_subseeds { get; set; } - public int subseed_strength { get; set; } + public float subseed_strength { get; set; } public int width { get; set; } public int height { get; set; } public int sampler_index { get; set; } @@ -303,21 +319,43 @@ public class Info public object[] styles { get; set; } public string job_timestamp { get; set; } public int clip_skip { get; set; } + } - public override string ToString() - { - return JsonSerializer.Serialize(this); - } + + + + + + + + + + + public class JsonResponseImg2Img : JsonResponseBase + { + public ParametersResponseImg2Img parameters { get; set; } } - public class Extra_Generation_Params + public class ParametersResponseImg2Img : ParametersBase { + public object init_images { get; set; } + public int resize_mode { get; set; } + public object mask { get; set; } + public int mask_blur { get; set; } + public int inpainting_fill { get; set; } + public bool inpaint_full_res { get; set; } + public int inpaint_full_res_padding { get; set; } + public int inpainting_mask_invert { get; set; } - public override string ToString() - { - return JsonSerializer.Serialize(this); - } + public bool include_init_images { get; set; } + } + + + + + public class Extra_Generation_Params + { } diff --git a/src/IvyPhotoshopDiffusion/FormMain.Designer.cs b/src/IvyPhotoshopDiffusion/FormMain.Designer.cs index ec45d3e..8816733 100644 --- a/src/IvyPhotoshopDiffusion/FormMain.Designer.cs +++ b/src/IvyPhotoshopDiffusion/FormMain.Designer.cs @@ -96,6 +96,8 @@ private void InitializeComponent() this.buttonGenerate.Size = new System.Drawing.Size(112, 41); this.buttonGenerate.TabIndex = 0; this.buttonGenerate.Text = "Generate"; + this.toolTip.SetToolTip(this.buttonGenerate, "Generate image\r\nText2Image, if [shift] key pressed. \r\nImage2Image, if no key pres" + + "sed"); this.buttonGenerate.UseVisualStyleBackColor = true; this.buttonGenerate.Click += new System.EventHandler(this.buttonGenerate_Click); // diff --git a/src/IvyPhotoshopDiffusion/FormMain.cs b/src/IvyPhotoshopDiffusion/FormMain.cs index 2e3ae2f..b587883 100644 --- a/src/IvyPhotoshopDiffusion/FormMain.cs +++ b/src/IvyPhotoshopDiffusion/FormMain.cs @@ -21,6 +21,7 @@ namespace Invary.IvyPhotoshopDiffusion { // Automatic1111 need command line option '--api', otherwise 404 error + //TODO: custom prompt selection, combobox //TODO: save last setting //TODO: dupe exec check? @@ -271,30 +272,54 @@ private void buttonGenerate_Click(object sender, EventArgs e) { try { - var requestImg2Img = new JsonRequestImg2Img(); + JsonRequestBase request; + + // text2image, if [shift] key pressed + if (Control.ModifierKeys.HasFlag(Keys.Shift)) + { + LogMessage.WriteLine("start Text2Image"); + request = new JsonRequestTxt2Img(); + } + else + request = new JsonRequestImg2Img(); int nBatchCount = 1; Invoke((MethodInvoker)delegate { - requestImg2Img.prompt = textBoxPrompt.Text; - requestImg2Img.negative_prompt = textBoxNegativePrompt.Text; - - requestImg2Img.denoising_strength = (float)trackBarNoiseScale100.Value / 100; - requestImg2Img.mask_blur = trackBarMaskBlur.Value; - requestImg2Img.cfg_scale = (float)trackBarCfgScale100.Value / 100; - requestImg2Img.steps = trackBarStep.Value; - requestImg2Img.sampler_index = (string)comboBoxSampler.SelectedItem; + request.prompt = textBoxPrompt.Text; + request.negative_prompt = textBoxNegativePrompt.Text; + + request.denoising_strength = (float)trackBarNoiseScale100.Value / 100; + request.cfg_scale = (float)trackBarCfgScale100.Value / 100; + request.steps = trackBarStep.Value; + request.sampler_index = (string)comboBoxSampler.SelectedItem; if (numericUpDownSeed.Value >= 0) - requestImg2Img.seed = numericUpDownSeed.Value; + request.seed = numericUpDownSeed.Value; - requestImg2Img.batch_size = trackBarBatchSize.Value; + request.batch_size = trackBarBatchSize.Value; nBatchCount = trackBarBatchCount.Value; - requestImg2Img.inpainting_mask_invert = (checkBoxInpainting_mask_invert.Checked) ? 1 : 0; + request.width = int.Parse((string)comboBoxWidth.SelectedItem); + request.height = int.Parse((string)comboBoxHeight.SelectedItem); + + + if (request.GetType() == typeof(JsonRequestImg2Img)) + { + var reqImg2Img = request as JsonRequestImg2Img; + reqImg2Img.mask_blur = trackBarMaskBlur.Value; + reqImg2Img.inpainting_mask_invert = (checkBoxInpainting_mask_invert.Checked) ? 1 : 0; + reqImg2Img.init_images = new string[1]; + } + + + if (request.GetType() == typeof(JsonRequestTxt2Img)) + { + var reqTxt2Img = request as JsonRequestTxt2Img; + //TODO: enable_hr + } }); - requestImg2Img.init_images = new string[1]; if (_bAbort) return; @@ -326,54 +351,57 @@ private void buttonGenerate_Click(object sender, EventArgs e) } - Photoshop.Copy(appRef, true); - - if (Clipboard.ContainsImage()) + if (request.GetType() == typeof(JsonRequestImg2Img)) { - using (Image img = Clipboard.GetImage()) - { - //img.Save(@"g:\desktop\14214.png"); + var reqImg2Img = request as JsonRequestImg2Img; - requestImg2Img.init_images[0] = Automatic1111.Image2String(img); - requestImg2Img.width = img.Width; - requestImg2Img.height = img.Height; + Photoshop.Copy(appRef, true); - if (img.Width != width || img.Height != height) + if (Clipboard.ContainsImage()) + { + using (Image img = Clipboard.GetImage()) { - LogMessage.WriteLine("error: generate failed"); - LogMessage.WriteLine($"Maybe selection location in photoshop is invalid. Selection area is out of image."); - return; - } + //img.Save(@"g:\desktop\14214.png"); - Invoke((MethodInvoker)delegate - { - var mask = pictureBoxMask.Image; - if (mask != null && checkBoxAutoMask.Checked == false) + reqImg2Img.init_images[0] = Automatic1111.Image2String(img); + + if (img.Width != width || img.Height != height) { - requestImg2Img.mask = Automatic1111.Image2String(mask); + LogMessage.WriteLine("error: generate failed"); + LogMessage.WriteLine($"Maybe selection location in photoshop is invalid. Selection area is out of image."); + return; + } - if (mask.Width != width || mask.Height != height) + Invoke((MethodInvoker)delegate + { + var mask = pictureBoxMask.Image; + if (mask != null && checkBoxAutoMask.Checked == false) { - LogMessage.WriteLine("error: generate failed"); - LogMessage.WriteLine($"Mask image size is invalid. Need to clear/set mask."); - return; + reqImg2Img.mask = Automatic1111.Image2String(mask); + + if (mask.Width != width || mask.Height != height) + { + LogMessage.WriteLine("error: generate failed"); + LogMessage.WriteLine($"Mask image size is invalid. Need to clear/set mask."); + return; + } } - } - else if (checkBoxAutoMask.Checked) - { - using (var bmpMask = CreateMask(img)) + else if (checkBoxAutoMask.Checked) { - requestImg2Img.mask = Automatic1111.Image2String(bmpMask); + using (var bmpMask = CreateMask(img)) + { + reqImg2Img.mask = Automatic1111.Image2String(bmpMask); + } } - } - }); + }); + } + } + else + { + LogMessage.WriteLine("error: generate failed"); + LogMessage.WriteLine("Failed to obtain image from photoshop"); + return; } - } - else - { - LogMessage.WriteLine("error: generate failed"); - LogMessage.WriteLine("Failed to obtain image from photoshop"); - return; } if (_bAbort) return; @@ -385,13 +413,13 @@ private void buttonGenerate_Click(object sender, EventArgs e) return; if (i > 0) - requestImg2Img.seed += requestImg2Img.batch_size; + request.seed += request.batch_size; if (nBatchCount > 1) { LogMessage.WriteLine($"Start batch {i + 1} / {nBatchCount}"); } - var responseObj = Automatic1111.Send(requestImg2Img); + var responseObj = Automatic1111.Send(request); foreach (var encodedimg in responseObj.images) { if (_bAbort) @@ -409,7 +437,10 @@ private void buttonGenerate_Click(object sender, EventArgs e) Photoshop.SetSelection(appRef, curSelection); } - LogMessage.WriteLine(responseObj.info.ToString().Replace(@"\r\n", "\r\n").Replace(@"\n", "\r\n")); + foreach (var item in responseObj.info.infotexts) + { + LogMessage.WriteLine(item); + } } if (_bAbort) return; diff --git a/src/IvyPhotoshopDiffusion/XmlSetting.cs b/src/IvyPhotoshopDiffusion/XmlSetting.cs index 9c49a99..8f2fc2e 100644 --- a/src/IvyPhotoshopDiffusion/XmlSetting.cs +++ b/src/IvyPhotoshopDiffusion/XmlSetting.cs @@ -20,7 +20,7 @@ public class XmlSetting [XmlIgnore] - public static int nVersion { get; } = 101; + public static int nVersion { get; } = 102; [XmlIgnore] public static string strVersion { get; } = $"Ver{nVersion}";