Aspect ratio sliders
Sliders adjust according to aspect ratio.
Default choices added to settings in user interface section Choices are editable by user
User selects from dropdown. When you move one slider, the other adjusts according to the ratio chosen. Vice versa for the other slider.
Number fields for changes work as well.
For disabling ratio, an unlock pad "🔓" is available as a default. This string can be changed to anything to serve as a disable, as long as there is no colon ":" in the string.
Ratios are entered in this format, floats or ints with a colon "1:1". The string is split at the colon, parses left and right as floats to perform the math.
More technical discussion about your changes go here, plus anything that a maintainer might have to specifically take a look at, or be wary of. I included the componentController library, as this uses it.
Environment this was tested in
- OS: Windows
- Browser: [Chrome and Firefox]
Now for the demos:
Video demonstration: https://user-images.githubusercontent.com/40751091/217967464-d9d9cb67-a195-4697-b11f-137d14cf42af.mp4
On settings tab:

On txt2img and img2img, it is a dropdown that looks like a button, it has an indicator that can hot swap the setting:

In the upper right corner is the indicator, it's clickable, this indicates it's in precision mode:

This indicates it's in rounding mode:
.
Changing round/precision mode literally changes and reads from the setting, making it hot swappable, no save and apply necessary unless you want to tell the app which value to use as default on start-up.
.
.
The reason it has two modes, models have a limitation of step 8. To keep a ratio intact and on a multiple of 8, we end up skipping 7 valid ratio coordinates for every perfect match. This is why there is rounding mode, so you can get close, and it rounds to a nearby step 8, which throws off the aspect ratio a little, but keeps you from having to do ratio math for every image, and keeps you from generating unnecessary stuff you'll crop out.
Rounding mode gives users options, some will want to round up, round nearest, or round down. This is to give them flexibility and makes it easier for users to know what behavior to expect when adjusting sliders.
.
.
The dropdown has choices of aspect ratios, these are configurable in settings:

When a ratio is selected in the dropdown/button, the sliders will initially snap to complimentary values, how accurate depends on your settings.
Then using either the sliders or number fields, the values will move accordingly (by precision/rounding and by ratio).
When you don't want them to have a ratio, there is an unlocked pad as a symbol, which is on by default. When the sliders are unlocked, it hides the indicator. This symbol can be changed in the settings as well.

The javascript class is setup to be reusable, just reference your element id's and call its static method for it to start it's own observer.
You will need to have two sliders, a dropdown that has your ratios, a checkbox for a rounding source and a radio for rounding method. This will allow others to implement it in their scripts/extensions.

I added the "buttons" as a column. Styled the dropdown to remove the 'svg' background-image drodown (created by svelte), I included the appearance rules to remove the default dropdown arrow (but the svelte component does it already), just in case.
Here is the updated look.

wow that very clean, nice work!
issue
resolution need to be in steps of 8
currently you're using Math.round() set it to the closest integer
but when the image is generated, the resolution is floored to the nearest multiple of 8
so if I set the aspect ratio to 16:9, the actual result will something likely be 16:8.95
personally I rather have 16:9.05 then 16:8.95 I think they should be an option to round up the number to the nearest multiple of 8 and I think rounding up the default option
I'm not sure how I would work the math for different ratios. I forget how to do math, the computer does it.
Something like, set the step size (of width) so it snaps at points where the other value (height) is a multiple of 8 and on the ratio.
Then set the step size the other way around (on height to affect width).
I feel like this is grade school math, something like greatest common denominator. 😆 Oh man.
forget how to do math
lol
I feel like this is grade school math
yes it is 😆
function roundStepUp(number, step) {
return Math.ceil(number / step ) * step;
}
console.log(roundStepUp(64, 8)) // 64
console.log(roundStepUp(64.1, 8)) // 72
console.log(roundStepUp(72, 8)) // 72
console.log(roundStepUp(127, 8)) // 128
console.log(roundStepUp(128, 8)) // 128
console.log(roundStepUp(129, 8)) // 136
forgot to mention there is no need to round down the number to an integer
I'm ready. Seems to be working. Have not tested it with a cinematic ratio. I forgot to remove the other 'rounds' that should not be needed.
@w-e-w Thanks for helping and holding me accountable. This is turning out alright.
no not working
wait a moment you made another commit
Huh. It's acting like I didn't trigger the change event when I change the dropdown.
nope, not working, still some issues
you can get values like 1000x563
563 is not a multiple of 8 and
and when it tries to generate a image of the size it freaks out
in my case it results in a image size of 1000x512
both numbers will have to be a multiple of 8
I'm not sure what you did but you seem to override the check that rounds down the number two multiples of 8 do not do so
in this case the resolution should be 1000x568
which correctly generated a image at the resolution of 1000x568
input w1000 at 16:9 should output a H of 568

both numbers should be multiple of 8 otherwise it's freaks out
I made a change on the slider component controller. I noticed it wasn't updating the backend in all scenarios, just some.
I do get the 568 height when on 1000.
I think the base it steps up from get thrown off, if any number hits the minimum.
I'm going to explore my logic. I might've missed something small.
Cool I like it
I noticed, when I use the up/down arrow in the number field, 16:9, it can change from 712 to 784 on width, while height stays at 424.
This means I need to rework the step logic for sure.
Could you take a look at this? It uses step of 64 instead of 8 https://github.com/preyx/sd-scale-calc/blob/main/docs/index.html
Could you take a look at this? It uses step of 64 instead of 8 https://github.com/preyx/sd-scale-calc/blob/main/docs/index.html
this thing looks quite old
see https://github.com/AUTOMATIC1111/stable-diffusion-webui/blob/master/modules/ui.py#L479
webui did use step 64 couple months ago but has since changed to use step 8 since
however if you are old user of webui backthen
since the config that controls the step value is stored in ui-config.json
the "step 8 update" will not apply
you will need to manually edit ui-config.json or delete it
letting the configuration file to be regenerated for you to have step slider in the UI
https://github.com/AUTOMATIC1111/stable-diffusion-webui/blob/master/modules/processing.py#L35 I believe this is what ultimately controls the "step value" the height and width of the image is integer divided by 8
sorry that I can only give suggestions and help debug I really need to learn JS someday
I think I understand the issue, there was a conflict, and my stuff was off. I removed the conflict. I have it in my head on how to fix it, but have to spell it out.
just in case there's any misunderstanding it is my understanding that the network can only be used at resolution in multiple of 8 (or maybe 16 depending on the model)
@w-e-w
So. I had a solution working, thought it was wrong, but it was correct, went full circle. I constrained it to multiples of 8. So it leaps to valid values where both are a correct aspect ratio but of a multiple of 8.
Even though a number like width 1040, and height 585 are a valid 16:9 ratio, they are not both a multiple of 8.
The same with 528x297.
If I do an image at 528x297 without using this tool, I get a result of 528x296.
The question becomes, would someone using this tool expect it to show values that are valid, when they adjust the sliders and it snaps to points, that it will be the size it says.
I imagine that if a person was wanting a particular aspect ratio, that the outcome would keep it intact.
It's too bad that we are on the multiple of 8 constraint, because there would be other sizes that are valid.
I think it's ready for another round of checks, I tested it with 1.85:1, but I can't do high numbers (I temporary changed the max on the sliders, they work as long as you have enough memory, tested with 64x2496 to see if I can go above 2048, and yes). But for 1.85:1, I can only test up to 1184x640.
good news
did some quick test and didn't find any issues I didn't find any bugs but I don't like it
bad news
I don't think enforcing that the aspect ratio is perfect is a good idea
first issue this makes this ratio slider FAR less useful
in an applications such as Photoshop or Gimp if you set a specify ratio, it is expected that the number is rounded to integer the use are not asking for Pixel Perfect ratio, as long as it's close enough here due to stable diffusion we need to round up to the nearest 8 pixel but the concepts still applies
if I specify is 9:16 image I don't care if its 9:16 or 9:16.14, if I do really need exact 9:16 I can crop the image after
what a user would want is Convenient method to set a ratio close enough to 9:16 that the difference doesn't matter that much
and in my opinion I would prefer the ratio to be round UP rather than down, image you want a image 9:16 with one side be w600, the ideal size will be 600x1067 (600x1066.667) due to step 8 this H will need to be round up and image will need to be 600x1072, I can easily crop this to 600x1067
but instead if I round down the image will be 600x1064, I will need to crop theis image to 599x1064 then scale it up by a small amount
note this is just an example and a bit exaggerated 8 pixel due to the relative size of the image doesn't really matter
the second issue of enforcing the perfect aspect ratio
for example 1:1.3
as you can see this tool becomes useless
(the slider is effectively not movable)
the solution
you simply need to round up the other number to the nearest multiple of 8
function roundStepUp(number, step) {
return Math.ceil(number / step ) * step;
}
https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/7601#issuecomment-1419784270
however someone do prefer rounding down, you simply have to change ceil to floor
if you do wish you can make a toggle in the settings for round up or down but personally I wouldn't bother
maybe someone do wish exact ratio (though I don't see it), I think you can keep this under an option
just let the user deal which non exact aspect ratio, the same way that it has been done in graphic softwares
gimp
the 1:1.3 example is quite sane, compared to the ratios we use for paper
https://en.wikipedia.org/wiki/Paper_size
I don't think I'm going to round it off. Some will expect pixel perfect and some wont care. It does have the ability to put in a different ratio. So if it needs to be slightly off, it can be done there to change the scaling.
I think that process keeps it predictable and flexible.
1:1.3 is so close to 1:1, why not use 1:1, go next step up and trim 6 pixels off one edge.
I get it. I'm going to poke around a little and think about it.
I get it. I'm going to poke around a little and think about it.
I know you get it but I like to reinforce the point
using the ratio 1.66:1 (a ratio you added)
there's only 2 valid steps with in 2000x2000 (the default max res)
and because I'm poor I'm using a 1650 4G
I can only use the first two step before OOM
I think I can say that this is objectively not useful

also if someone wished you printed the image out they might want to set it to A4 ratio
the actual of A series paper is ratio 1:√2,
even using the roughest approximation 1:1.4
the slider becomes completely unusable

an additional point any user who have used webui would know that they can only adjust the resolution in steps of 8 so I don't think it will ba a surprise to anyone that the ratio slider is also limited to steps of 8
if you really want it so that people can know that they're using the exact ratio maybe change the color of the button or text to green when the ratio is exact use an indication of some kind
Cool. Then we can scrap the whole thing. I was doing this for fun on some time off. But now it's becoming a chore, if it I really wanted to do a chore, I could fold some clothes instead.
I put it in the open so others can have a whack at it as well. It shouldn't fall on my shoulders only, I did the hard part already.
Cool. Then we can scrap the whole thing. I was doing this for fun on some time off. But now it's becoming a chore, if it I really wanted to do a chore, I could fold some clothes instead.
apologies if I sound pushy I'm merely trying to give as much as advice as possible
I intend to try and poke around in JS the code (I actually did try yesterday but I failed) after I finish debugging the stable-diffusion-webui-daam extension
just remembered I have a short presentation tomorrow 8:30 a.m. didn't sleep all night
I had figured out how to add in support for decimals when using a gcd. I wasn't thinking others were going to be using it a lot. It was never going to be added, but I threw it in last minute, just so it can do 1.85:1, because I thought there might be some that people would need. But it feels like every feature I add, it brings all other issues. I just want to see this thing get released, and it feels like there's always another corner before I can find the release point.
It's just a bit frustrating, because I had the code for rounding, and thought it wasn't good enough, so I wrote over it, and now, I need to do it again.