Hi @Federico_Catala_Erro,

Welcome to the forum!

I was curious as to whether a decimal input was possible or practical. To give you a demo of why it’s not practical in my opinion, I looked up a how to convert a decimal to a fraction. I made a Lua script based on that:

It’s doable if you use it carefully… But as you can imagine, it’s faster, easier and more reliable to calculate, say, `1.77778`

from `16 : 9`

than the reverse. In general, software designers and programmers have to develop defensively.

[Edit: If you restyle the while loop to stop if either the numerator or the denominator grow beyond a limit, like 16… Then maybe my opinion changes and this has more promise. Either way, it was fun to think about and test. ]

```
-- Stack Overflow solution by onyambu
-- https://stackoverflow.com/a/64828741
local function toRatio(number, cycles, precision)
local cVerif = cycles or 10
local pVerif = precision or 5e-4
cVerif = math.max(1, math.abs(cycles))
pVerif = math.max(1e-10, math.abs(pVerif))
local sgnNum = 0
if number > 0 then sgnNum = 1 end
if number < 0 then sgnNum = -1 end
if number == 0 then return 0, 0 end
local absNum = math.abs(number)
local truncNum = math.tointeger(absNum)
local fracNum = absNum - truncNum
local aVec = { truncNum, 1 }
local bVec = { 1, 0 }
local counter = 0
while fracNum > pVerif and counter < cVerif do
local newNum = 1.0 / fracNum
local integral = math.tointeger(newNum)
local temp = aVec
aVec = { integral * aVec[1] + bVec[1],
integral * aVec[2] + bVec[2] }
bVec = temp
fracNum = newNum - integral
counter = counter + 1
end
return sgnNum * aVec[1], aVec[2]
end
local dlg = Dialog { title = "Custom Pixel Aspect" }
local function updateLabel()
local args = dlg.data
local aspectRatio = args.aspectRatio
local cycles = args.cycles
local precision = args.precision
local ant, cons = toRatio(aspectRatio, cycles, precision)
local str = string.format("%d : %d", ant, cons)
dlg:modify { id = "decLabel", text = str }
end
dlg:number {
id = "aspectRatio",
label = "Aspect:",
text = "1.0",
decimals = 5,
onchange = updateLabel
}
dlg:slider {
id = "cycles",
label = "Cycles:",
value = 10,
min = 1,
max = 20,
onchange = updateLabel
}
dlg:number {
id = "precision",
label = "Precision",
text = string.format("%.8f", 5e-4),
decimals = 6,
onchange = updateLabel
}
dlg:newrow { always = false }
dlg:label {
id = "decLabel",
label = "Ratio:",
text = "1:1"
}
dlg:newrow { always = false }
dlg:button {
id = "confirm",
text = "&OK",
focus = false,
onclick = function()
local activeSprite = app.activeSprite
if not activeSprite then return end
local args = dlg.data
local aspectRatio = args.aspectRatio
local precision = args.precision
local cycles = args.cycles
local ant, cons = toRatio(aspectRatio, cycles, precision)
if ant == 0 then return end
if cons == 0 then return end
ant = math.abs(ant)
cons = math.abs(cons)
-- There should be some reasonable stopping point...
local stopPoint = 16
if ant >= stopPoint or cons >= stopPoint then
app.alert("Ratio too large.")
return
end
-- Do not assign Size(0, 0) or a size with either
-- negative width or negative height to pixel ratio.
activeSprite.pixelRatio = Size(ant, cons)
end
}
dlg:button {
id = "cancel",
text = "&CANCEL",
focus = true,
onclick = function()
dlg:close()
end
}
dlg:show { wait = false }
```

(Custom aspect ratios done by script are not picked up by the new sprite or sprite properties dialog, which is an advantage of the XML.)

Cheers,

Jeremy