Hiresfix for img2imgchiragn888/Stable_difussion#14
![Logo of Sweep](/_next/image?url=%2Flogo.png&w=64&q=75)
Hiresfix for img2img
chiragn888/Stable_difussion#14
> > >
✓ Completed in 7 minutes, 5 months ago using GPT-4  •  Book a call  •  Report a bug
Progress
  Create
extensions-builtin/extra-options-section/scripts/hires_fix.py
b749bca
 1import torch
2from torchvision.transforms import functional as TF
3
4
5def apply_hires_fix(image_input, denoise_strength, model, device='cuda'):
6 """
7 Applies the Hires fix to img2img operations.
8
9 Parameters:
10 - image_input: A PIL Image or a tensor representing the input image.
11 - denoise_strength: Float, the strength of the denoise effect.
12 - model: The neural network model used for image generation.
13 - device: The device to perform computations on.
14
15 Returns:
16 - A tensor representing the processed image.
17 """
18 # Convert PIL Image to tensor if necessary
19 if not isinstance(image_input, torch.Tensor):
20 image_input = TF.to_tensor(image_input).unsqueeze(0).to(device)
21
22 # Pre-process the image as needed for the Hires fix
23 # This might include resizing, normalization, etc.
24 # Placeholder for actual pre-processing logic
25 processed_image = image_input
26
27 # Adjust model parameters for Hires fix
28 # Placeholder for model adjustment logic
29
30 # Generate the image with the model
31 with torch.no_grad():
32 output = model(processed_image, denoise_strength)
33
34 # Post-process the output as needed for the Hires fix
35 # This might include resizing back, denormalization, etc.
36 # Placeholder for actual post-processing logic
37 final_output = output
38
39 return final_output
40
- Create a new Python script named
hires_fix.py
in theextensions-builtin/extra-options-section/scripts/
directory. This script will contain the logic for applying the "Hires fix" to img2img operations. - Import necessary dependencies at the top of the file, such as TensorFlow or PyTorch, depending on the model's requirements.
- Define a function
apply_hires_fix
that takes parameters for the image input, denoise strength, and any other relevant parameters for the "Hires fix". This function will modify the image generation parameters to apply the "Hires fix". - Ensure that this script can be imported and used by other parts of the application, particularly where img2img operations are handled.
  Run GitHub Actions for
extensions-builtin/extra-options-section/scripts/hires_fix.pyÂ
Ran GitHub Actions for b749bca53efe6de59704829a94e071d7d71479b1:
  ModifyChanged
javascript/aspectRatioOverlay.js:69-113Â
Changed javascript/aspectRatioOverlay.js
in f3d6221
   Â
1 | |||
2 | let currentWidth = null; | ||
3 | let currentHeight = null; | ||
4 | let arFrameTimeout = setTimeout(function() {}, 0); | ||
5 | |||
6 | function dimensionChange(e, is_width, is_height) { | ||
7 | |||
8 | if (is_width) { | ||
9 | currentWidth = e.target.value * 1.0; | ||
10 | } | ||
11 | if (is_height) { | ||
12 | currentHeight = e.target.value * 1.0; | ||
13 | } | ||
14 | |||
15 | var inImg2img = gradioApp().querySelector("#tab_img2img").style.display == "block"; | ||
16 | |||
17 | if (!inImg2img) { | ||
18 | return; | ||
19 | } | ||
20 | |||
21 | var targetElement = null; | ||
22 | |||
23 | var tabIndex = get_tab_index('mode_img2img'); | ||
24 | if (tabIndex == 0) { // img2img | ||
25 | targetElement = gradioApp().querySelector('#img2img_image div[data-testid=image] img'); | ||
26 | } else if (tabIndex == 1) { //Sketch | ||
27 | targetElement = gradioApp().querySelector('#img2img_sketch div[data-testid=image] img'); | ||
28 | } else if (tabIndex == 2) { // Inpaint | ||
29 | targetElement = gradioApp().querySelector('#img2maskimg div[data-testid=image] img'); | ||
30 | } else if (tabIndex == 3) { // Inpaint sketch | ||
31 | targetElement = gradioApp().querySelector('#inpaint_sketch div[data-testid=image] img'); | ||
32 | } | ||
33 | |||
34 | |||
35 | if (targetElement) { | ||
36 | |||
37 | var arPreviewRect = gradioApp().querySelector('#imageARPreview'); | ||
38 | if (!arPreviewRect) { | ||
39 | arPreviewRect = document.createElement('div'); | ||
40 | arPreviewRect.id = "imageARPreview"; | ||
41 | gradioApp().appendChild(arPreviewRect); | ||
42 | } | ||
43 | |||
44 | |||
45 | |||
46 | var viewportOffset = targetElement.getBoundingClientRect(); | ||
47 | |||
48 | var viewportscale = Math.min(targetElement.clientWidth / targetElement.naturalWidth, targetElement.clientHeight / targetElement.naturalHeight); | ||
49 | |||
50 | var scaledx = targetElement.naturalWidth * viewportscale; | ||
51 | var scaledy = targetElement.naturalHeight * viewportscale; | ||
52 | |||
53 | var cleintRectTop = (viewportOffset.top + window.scrollY); | ||
54 | var cleintRectLeft = (viewportOffset.left + window.scrollX); | ||
55 | var cleintRectCentreY = cleintRectTop + (targetElement.clientHeight / 2); | ||
56 | var cleintRectCentreX = cleintRectLeft + (targetElement.clientWidth / 2); | ||
57 | |||
58 | var arscale = Math.min(scaledx / currentWidth, scaledy / currentHeight); | ||
59 | var arscaledx = currentWidth * arscale; | ||
60 | var arscaledy = currentHeight * arscale; | ||
61 | |||
62 | var arRectTop = cleintRectCentreY - (arscaledy / 2); | ||
63 | var arRectLeft = cleintRectCentreX - (arscaledx / 2); | ||
64 | var arRectWidth = arscaledx; | ||
65 | var arRectHeight = arscaledy; | ||
66 | |||
67 | arPreviewRect.style.top = arRectTop + 'px'; | ||
68 | arPreviewRect.style.left = arRectLeft + 'px'; | ||
69 | arPreviewRect.style.width = arRectWidth + 'px'; | ||
70 | arPreviewRect.style.height = arRectHeight + 'px'; | ||
71 | |||
72 | clearTimeout(arFrameTimeout); | ||
73 | arFrameTimeout = setTimeout(function() { | ||
74 | arPreviewRect.style.display = 'none'; | ||
75 | }, 2000); | ||
76 | |||
77 | arPreviewRect.style.display = 'block'; | ||
78 | |||
79 | } | ||
80 | |||
81 | } | ||
82 | |||
83 | |||
84 | onAfterUiUpdate(function() { | ||
85 | var arPreviewRect = gradioApp().querySelector('#imageARPreview'); | ||
86 | if (arPreviewRect) { | ||
87 | arPreviewRect.style.display = 'none'; | ||
88 | } | ||
89 | var tabImg2img = gradioApp().querySelector("#tab_img2img"); | ||
90 | if (tabImg2img) { | ||
91 | var inImg2img = tabImg2img.style.display == "block"; | ||
92 | if (inImg2img) { | ||
93 | let inputs = gradioApp().querySelectorAll('input'); | ||
94 | inputs.forEach(function(e) { | ||
95 | var is_width = e.parentElement.id == "img2img_width"; | ||
96 | var is_height = e.parentElement.id == "img2img_height"; | ||
97 | |||
98 | if ((is_width || is_height) && !e.classList.contains('scrollwatch')) { | ||
99 | e.addEventListener('input', function(e) { | ||
100 | dimensionChange(e, is_width, is_height); | ||
101 | }); | ||
102 | e.classList.add('scrollwatch'); | ||
103 | } | ||
104 | if (is_width) { | ||
105 | currentWidth = e.value * 1.0; | ||
106 | } | ||
107 | if (is_height) { | ||
108 | currentHeight = e.value * 1.0; | ||
109 | } | ||
110 | }); | ||
111 | } | ||
112 | } | ||
113 | }); | 1 | |
2 | let currentWidth = null; | ||
3 | let currentHeight = null; | ||
4 | let arFrameTimeout = setTimeout(function() {}, 0); | ||
5 | |||
6 | function dimensionChange(e, is_width, is_height) { | ||
7 | |||
8 | if (is_width) { | ||
9 | currentWidth = e.target.value * 1.0; | ||
10 | } | ||
11 | if (is_height) { | ||
12 | currentHeight = e.target.value * 1.0; | ||
13 | } | ||
14 | |||
15 | var inImg2img = gradioApp().querySelector("#tab_img2img").style.display == "block" && window.hiresFixEnabled; | ||
16 | |||
17 | if (!inImg2img) { | ||
18 | return; | ||
19 | } | ||
20 | |||
21 | var targetElement = null; | ||
22 | |||
23 | var tabIndex = get_tab_index('mode_img2img'); | ||
24 | if (tabIndex == 0) { // img2img | ||
25 | targetElement = gradioApp().querySelector('#img2img_image div[data-testid=image] img'); | ||
26 | } else if (tabIndex == 1) { //Sketch | ||
27 | targetElement = gradioApp().querySelector('#img2img_sketch div[data-testid=image] img'); | ||
28 | } else if (tabIndex == 2) { // Inpaint | ||
29 | targetElement = gradioApp().querySelector('#img2maskimg div[data-testid=image] img'); | ||
30 | } else if (tabIndex == 3) { // Inpaint sketch | ||
31 | targetElement = gradioApp().querySelector('#inpaint_sketch div[data-testid=image] img'); | ||
32 | } | ||
33 | |||
34 | |||
35 | if (targetElement) { | ||
36 | |||
37 | var arPreviewRect = gradioApp().querySelector('#imageARPreview'); | ||
38 | if (!arPreviewRect) { | ||
39 | arPreviewRect = document.createElement('div'); | ||
40 | arPreviewRect.id = "imageARPreview"; | ||
41 | gradioApp().appendChild(arPreviewRect); | ||
42 | } | ||
43 | |||
44 | |||
45 | // Add Hires fix checkbox | ||
46 | var hiresFixContainer = document.createElement('div'); | ||
47 | hiresFixContainer.id = "hiresFixContainer"; | ||
48 | var hiresFixCheckbox = document.createElement('input'); | ||
49 | hiresFixCheckbox.type = "checkbox"; | ||
50 | hiresFixCheckbox.id = "hiresFixCheckbox"; | ||
51 | var hiresFixLabel = document.createElement('label'); | ||
52 | hiresFixLabel.htmlFor = "hiresFixCheckbox"; | ||
53 | hiresFixLabel.innerText = "Enable Hires fix"; | ||
54 | hiresFixContainer.appendChild(hiresFixCheckbox); | ||
55 | hiresFixContainer.appendChild(hiresFixLabel); | ||
56 | gradioApp().querySelector("#tab_img2img").appendChild(hiresFixContainer); | ||
57 | |||
58 | var viewportOffset = targetElement.getBoundingClientRect(); | ||
59 | |||
60 | var viewportscale = Math.min(targetElement.clientWidth / targetElement.naturalWidth, targetElement.clientHeight / targetElement.naturalHeight); | ||
61 | |||
62 | var scaledx = targetElement.naturalWidth * viewportscale; | ||
63 | var scaledy = targetElement.naturalHeight * viewportscale; | ||
64 | |||
65 | var cleintRectTop = (viewportOffset.top + window.scrollY); | ||
66 | var cleintRectLeft = (viewportOffset.left + window.scrollX); | ||
67 | var cleintRectCentreY = cleintRectTop + (targetElement.clientHeight / 2); | ||
68 | var cleintRectCentreX = cleintRectLeft + (targetElement.clientWidth / 2); | ||
69 | |||
70 | var arscale = Math.min(scaledx / currentWidth, scaledy / currentHeight); | ||
71 | var arscaledx = currentWidth * arscale; | ||
72 | var arscaledy = currentHeight * arscale; | ||
73 | |||
74 | var arRectTop = cleintRectCentreY - (arscaledy / 2); | ||
75 | var arRectLeft = cleintRectCentreX - (arscaledx / 2); | ||
76 | var arRectWidth = arscaledx; | ||
77 | var arRectHeight = arscaledy; | ||
78 | |||
79 | arPreviewRect.style.top = arRectTop + 'px'; | ||
80 | arPreviewRect.style.left = arRectLeft + 'px'; | ||
81 | arPreviewRect.style.width = arRectWidth + 'px'; | ||
82 | arPreviewRect.style.height = arRectHeight + 'px'; | ||
83 | |||
84 | clearTimeout(arFrameTimeout); | ||
85 | arFrameTimeout = setTimeout(function() { | ||
86 | arPreviewRect.style.display = 'none'; | ||
87 | }, 2000); | ||
88 | |||
89 | arPreviewRect.style.display = 'block'; | ||
90 | |||
91 | } | ||
92 | |||
93 | } | ||
94 | |||
95 | |||
96 | onAfterUiUpdate(function() { | ||
97 | var arPreviewRect = gradioApp().querySelector('#imageARPreview'); | ||
98 | if (arPreviewRect) { | ||
99 | arPreviewRect.style.display = 'none'; | ||
100 | } | ||
101 | var tabImg2img = gradioApp().querySelector("#tab_img2img"); | ||
102 | if (tabImg2img) { | ||
103 | // Event listener for Hires fix checkbox | ||
104 | var hiresFixCheckbox = gradioApp().querySelector("#hiresFixCheckbox"); | ||
105 | if (hiresFixCheckbox) { | ||
106 | hiresFixCheckbox.addEventListener('change', function() { | ||
107 | window.hiresFixEnabled = hiresFixCheckbox.checked; | ||
108 | }); | ||
109 | } | ||
110 | var inImg2img = tabImg2img.style.display == "block"; | ||
111 | if (inImg2img) { | ||
112 | let inputs = gradioApp().querySelectorAll('input'); | ||
113 | inputs.forEach(function(e) { | ||
114 | var is_width = e.parentElement.id == "img2img_width"; | ||
115 | var is_height = e.parentElement.id == "img2img_height"; | ||
116 | |||
117 | if ((is_width || is_height) && !e.classList.contains('scrollwatch')) { | ||
118 | e.addEventListener('input', function(e) { | ||
119 | dimensionChange(e, is_width, is_height); | ||
120 | }); | ||
121 | e.classList.add('scrollwatch'); | ||
122 | } | ||
123 | if (is_width) { | ||
124 | currentWidth = e.value * 1.0; | ||
125 | } | ||
126 | if (is_height) { | ||
127 | currentHeight = e.value * 1.0; | ||
128 | } | ||
129 | }); | ||
130 | } | ||
131 | } | ||
132 | }); | ||
133 | // Restore Hires fix checkbox state | ||
134 | var hiresFixCheckbox = gradioApp().querySelector("#hiresFixCheckbox"); | ||
135 | if (hiresFixCheckbox) { | ||
136 | hiresFixCheckbox.checked = window.hiresFixEnabled || false; | ||
137 | } |
- Add a new checkbox or toggle UI component within the img2img tab for enabling the "Hires fix". This will involve adding HTML for the checkbox and a label explaining its purpose.
- Within the
onAfterUiUpdate
function, add an event listener for the new "Hires fix" checkbox. When the checkbox is toggled, set a global or scoped variable to indicate whether the "Hires fix" should be applied. - Modify the
dimensionChange
event listener function to check if the "Hires fix" is enabled. If so, pass the necessary parameters (e.g., denoise strength) to the backend when img2img operations are triggered. - Ensure that the state of the "Hires fix" option is correctly managed between UI updates to preserve the user's selection.
Modified file with Assistant API
  Run GitHub Actions for
javascript/aspectRatioOverlay.jsÂ
Ran GitHub Actions for f3d6221b5d9cc3d2e5da58ce640fb94bb16acdd7:
Plan
This is based on the results of the Planning step. The plan may expand from failed GitHub Actions runs.
  Create
extensions-builtin/extra-options-section/scripts/hires_fix.py
b749bca
 1import torch
2from torchvision.transforms import functional as TF
3
4
5def apply_hires_fix(image_input, denoise_strength, model, device='cuda'):
6 """
7 Applies the Hires fix to img2img operations.
8
9 Parameters:
10 - image_input: A PIL Image or a tensor representing the input image.
11 - denoise_strength: Float, the strength of the denoise effect.
12 - model: The neural network model used for image generation.
13 - device: The device to perform computations on.
14
15 Returns:
16 - A tensor representing the processed image.
17 """
18 # Convert PIL Image to tensor if necessary
19 if not isinstance(image_input, torch.Tensor):
20 image_input = TF.to_tensor(image_input).unsqueeze(0).to(device)
21
22 # Pre-process the image as needed for the Hires fix
23 # This might include resizing, normalization, etc.
24 # Placeholder for actual pre-processing logic
25 processed_image = image_input
26
27 # Adjust model parameters for Hires fix
28 # Placeholder for model adjustment logic
29
30 # Generate the image with the model
31 with torch.no_grad():
32 output = model(processed_image, denoise_strength)
33
34 # Post-process the output as needed for the Hires fix
35 # This might include resizing back, denormalization, etc.
36 # Placeholder for actual post-processing logic
37 final_output = output
38
39 return final_output
40
  Run GitHub Actions for
extensions-builtin/extra-options-section/scripts/hires_fix.pyÂ
  Modify
javascript/aspectRatioOverlay.js:69-113Â
  Run GitHub Actions for
javascript/aspectRatioOverlay.jsÂ
Code Snippets Found
This is based on the results of the Searching step.
CHANGELOG.md:120-121
 120* style: file-metadata word-break ([#12837](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/12837))
121* revert SGM noise multiplier change for img2img because it breaks hires fix
CHANGELOG.md:170-194
 170### Features:
171 * refiner support [#12371](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/12371)
172 * add NV option for Random number generator source setting, which allows to generate same pictures on CPU/AMD/Mac as on NVidia videocards
173 * add style editor dialog
174 * hires fix: add an option to use a different checkpoint for second pass ([#12181](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/12181))
175 * option to keep multiple loaded models in memory ([#12227](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/12227))
176 * new samplers: Restart, DPM++ 2M SDE Exponential, DPM++ 2M SDE Heun, DPM++ 2M SDE Heun Karras, DPM++ 2M SDE Heun Exponential, DPM++ 3M SDE, DPM++ 3M SDE Karras, DPM++ 3M SDE Exponential ([#12300](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/12300), [#12519](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/12519), [#12542](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/12542))
177 * rework DDIM, PLMS, UniPC to use CFG denoiser same as in k-diffusion samplers:
178 * makes all of them work with img2img
179 * makes prompt composition posssible (AND)
180 * makes them available for SDXL
181 * always show extra networks tabs in the UI ([#11808](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/11808))
182 * use less RAM when creating models ([#11958](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/11958), [#12599](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/12599))
183 * textual inversion inference support for SDXL
184 * extra networks UI: show metadata for SD checkpoints
185 * checkpoint merger: add metadata support
186 * prompt editing and attention: add support for whitespace after the number ([ red : green : 0.5 ]) (seed breaking change) ([#12177](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/12177))
187 * VAE: allow selecting own VAE for each checkpoint (in user metadata editor)
188 * VAE: add selected VAE to infotext
189 * options in main UI: add own separate setting for txt2img and img2img, correctly read values from pasted infotext, add setting for column count ([#12551](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/12551))
190 * add resize handle to txt2img and img2img tabs, allowing to change the amount of horizontable space given to generation parameters and resulting image gallery ([#12687](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/12687), [#12723](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/12723))
191 * change default behavior for batching cond/uncond -- now it's on by default, and is disabled by an UI setting (Optimizatios -> Batch cond/uncond) - if you are on lowvram/medvram and are getting OOM exceptions, you will need to enable it
192 * show current position in queue and make it so that requests are processed in the order of arrival ([#12707](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/12707))
193 * add `--medvram-sdxl` flag that only enables `--medvram` for SDXL models
194 * prompt editing timeline has separate range for first pass and hires-fix pass (seed breaking change) ([#12457](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/12457))
README.md:60-75
 60- Prompt Editing, a way to change prompt mid-generation, say to start making a watermelon and switch to anime girl midway
61- Batch Processing, process a group of files using img2img
62- Img2img Alternative, reverse Euler method of cross attention control
63- Highres Fix, a convenience option to produce high resolution pictures in one click without usual distortions
64- Reloading checkpoints on the fly
65- Checkpoint Merger, a tab that allows you to merge up to 3 checkpoints into one
66- [Custom scripts](https://github.com/AUTOMATIC1111/stable-diffusion-webui/wiki/Custom-Scripts) with many extensions from community
67- [Composable-Diffusion](https://energy-based-model.github.io/Compositional-Visual-Generation-with-Composable-Diffusion-Models/), a way to use multiple prompts at once
68 - separate prompts using uppercase `AND`
69 - also supports weights for prompts: `a cat :1.2 AND a dog AND a penguin :2.2`
70- No token limit for prompts (original stable diffusion lets you use up to 75 tokens)
71- DeepDanbooru integration, creates danbooru style tags for anime prompts
72- [xformers](https://github.com/AUTOMATIC1111/stable-diffusion-webui/wiki/Xformers), major speed increase for select cards: (add `--xformers` to commandline args)
73- via extension: [History tab](https://github.com/yfszzx/stable-diffusion-webui-images-browser): view, direct and delete images conveniently within the UI
74- Generate forever option
75- Training tab
javascript/aspectRatioOverlay.js:69-113
 69 arPreviewRect.style.width = arRectWidth + 'px';
70 arPreviewRect.style.height = arRectHeight + 'px';
71
72 clearTimeout(arFrameTimeout);
73 arFrameTimeout = setTimeout(function() {
74 arPreviewRect.style.display = 'none';
75 }, 2000);
76
77 arPreviewRect.style.display = 'block';
78
79 }
80
81}
82
83
84onAfterUiUpdate(function() {
85 var arPreviewRect = gradioApp().querySelector('#imageARPreview');
86 if (arPreviewRect) {
87 arPreviewRect.style.display = 'none';
88 }
89 var tabImg2img = gradioApp().querySelector("#tab_img2img");
90 if (tabImg2img) {
91 var inImg2img = tabImg2img.style.display == "block";
92 if (inImg2img) {
93 let inputs = gradioApp().querySelectorAll('input');
94 inputs.forEach(function(e) {
95 var is_width = e.parentElement.id == "img2img_width";
96 var is_height = e.parentElement.id == "img2img_height";
97
98 if ((is_width || is_height) && !e.classList.contains('scrollwatch')) {
99 e.addEventListener('input', function(e) {
100 dimensionChange(e, is_width, is_height);
101 });
102 e.classList.add('scrollwatch');
103 }
104 if (is_width) {
105 currentWidth = e.value * 1.0;
106 }
107 if (is_height) {
108 currentHeight = e.value * 1.0;
109 }
110 });
111 }
112 }
113});