Bildausschnitt justieren
Die Aufgabe ist, den Ausschnitt eines Bildes, basierend auf den Originalmaßen, in einem Viewport zu justieren, so dass er bildfüllend dargestellt wird. Dazu ist zunächst der Zoomfaktor (Breite des dargestellten Images, wi) zu berechnen und dann noch die Offsets in x und y.
Variablen
xo1,yo1,xo2,yo2 | Ecken des Ausschnitts im Original | ||
xi1,yi1,xi2,yi2 | Ecken des Ausschnitts im Image | ||
dix, diy | Ausdehnung des Ausschnitts im dargestellten Image | ||
wvp | Breite des Viewports | hvp | Höhe des Viewports |
wo | Breite des Image (original) | ho | Höhe des Image (original) |
ar | Seitenverhältnis x/y | ||
wi | Breite des Image (dargestellt) | hi | Höhe des Image (dargestellt) |
offsx | Offset des linken Randes (Image → Viewport) | offsy | Offset des oberen Randes (Image → Viewport) |
foi | Faktor zur Umrechnung Originalkoordinate ⇒ Imagekordinate |
Berechnung
Anteil des Ausschnitts an der Ausdehnung des Originals:
(1) zx = (xo2 - xo1) / wo zy = (yo2 - yo1) / ho
Es gilt weiterhin für die Darstellung (zx und zy entsprechen den eben berechneten Werten):
(2) zx = dix / wi zy = diy / hi
Da der Ausschnitt in den Viewport passen soll, gilt weiterhin:
(3) dix = wvp diy = hvp
Gemäß der Berechnung (1) sind zx
und zy
bekannt und (3) kann nach wi
umgestellt und die Werte des Originals eingesetzt werdenwerden:
(4) wi{1} = wvp / zx hi = hvp / zy oder wi{2} = hvp / zy * ar = hvp / zy * wo / ho nach Einsetzung: wi{1} = wvp * wo / (xo2 - xo1) wi{2} = hvp * wo / ho * ho / (yo2 - yo1) = hvp * wo / (yo2 - yo1)
Damit der Ausschnitt in beiden Richtungen in den Viewport passt, muss der kleinere der beiden Werte für die weiteren Berechnungen angesetzt werden und damit ergeben sich die Darstellungsmaße für den Ausschnitt des Images im Viewport gemäß (2):
(5) wi = min(wi{1}, wi{2}) hi = wi / ar dix = zx * wi = (xo2 - xo1) / wo * wi diy = zy * hi oder diy = zy * wi / ar = (yo2 - yo1) / ho * wi / wo * ho = (yo2 - yo1) * wi / wo
Die Ecken des Ausschnitts im Image (und damit die Offsets des Images im Viewport, xi2 und yi2 werden nicht benötigt) ergeben sich zu:
(6) foi = wi / wo xi1 = xo1 * foi = xo1 * wi / wo yi1 = yo1 * foi = yo1 * wi / wo xi2 = xo2 * foi = xo2 * wi / wo yi2 = yo2 * foi = yo2 * wi / wo
Um die Offsets zu berechnen, bewegt man sich vom Rand des Viewports zu dessen Mitte und von dort zum Rand des Images, also für den X-Offset:
(7) offsx = wvp / 2 - dix / 2 - xi1 nach Einsetzung der Werte des Originals offsx = wvp / 2 - (xo2 - xo1) * wi / wo / 2 - xo1 * wi / wo offsx = wvp / 2 - (xo2 - xo1 + 2 * xo1) * wi / wo / 2 offsx = wvp / 2 - (xo1 + xo2) * wi / wo / 2
Zusammenfassung
Zusammengefasst ergeben sich folgende Berechnungen:
wi = wo * min(wvp / (xo2 - xo1), hvp / (yo2 - yo1)) offsx = wvp / 2 - (xo1 + xo2) * wi / wo / 2 offsx = hvp / 2 - (yo1 + yo2) * wi / wo / 2