Maße eines Vorschaubildes berechnen
Unsere Fotoapparate und Smartfone produzieren Bilder mit mehreren Millionen Bildpunkten. Viele Details einzufangen und mit anderen zu teilen ist häufig beabsichtigt. Oft ist allerdings auch ratsam, mit kleineren Versionen der Bilder zu arbeiten, denn mit vielen Pixeln geht ein großes Datenvolumen einher. Dieses sowie die Übertragungskapazität pro Zeiteinheit ist insbesondere bei mobilen Zugängen zum weltweiten Netz beschränkt. Ein kleines Vorschaubild spart Zeit, Geld, Strom.
Um sich als Autor diese Ersparnisse nicht durch neue Arbeit erkaufen zu müssen, ist wünschenswert, dass Vorschaubilder automatisch erstellt werden. Für den Aneamal-Konverter habe ich nun eine solche Funktion implementiert. Auf dieser Seite geht es darum, wie man aus Größenvorgaben fürs Vorschaubild die tatsächlichen Maße der automatisch zu erstellenden Bilder berechnen kann. Diese Berechnungen übernimmt das Programm im Hintergrund; weder Autor noch Leser werden damit behelligt.
Definitionen
- $b_o$
- Breite des Orignialbildes in Pixeln, $b_o>0$
- $b_a$
- Breite des Ausschnitts, der aus dem Originalbald fürs neue Bild verwendet wird, in Pixeln
- $b_v$
- Vorgabe für die Breite des Vorschaubildes
- $b_n$
- tatsächliche Breite des Vorschaubildes in Pixeln
- $h_o$
- Höhe des Originalbildes in Pixeln, $h_o>0$
- $h_a$
- Höhe des Ausschnitts, der aus dem Originalbald fürs neue Bild verwendet wird, in Pixeln
- $h_v$
- Vorgabe für die Höhe des Vorschaubildes
- $h_n$
- tatsächliche Höhe des Vorschaubildes in Pixeln
- $\min\left\{\ldots,\ldots\right\}$
- das dem Wert nach kleinste der durch Kommas getrennten Elemente der Menge1
- $\lfloor\ldots\rceil$
- steht fürs Runden des Ausdrucks auf die naheste ganze Zahl
- $\lfloor\ldots\rceil_+$
- steht fürs Runden des Ausdrucks auf die naheste positive ganze Zahl2
Ausschnitt
Der Ausschnitt des Originalbildes, der fürs Erstellen des Vorschaubildes verwendet wird, entspricht normalerweise dem gesamten Originalbild, das heißt $b_a=b_o$ und $h_a=h_o$. Je nach Vorgaben kann es aber dazu kommen, dass die Seitenverhältnisse von Original und neuem Bild nicht übereinstimmen. In jenem Fall wird ein passender zentraler Ausschnitt aus dem Original verwendet.
Wenn das Originalbild bei den Koordinaten $x_o=0, y_o=0$ beginnt und sich in positive Richtung aufspannt, liegt der Beginn eines mittigen Ausschnitts bei den Koordinaten
Vorgaben
Um ein Vorschaubild automatisch zu erstellen, braucht es eine Vorgabe zu seiner Größe. Eine Möglichkeit wäre, die Fläche festzulegen, sodass die Vorschaubilder unabhängig von ihrer Form möglichst immer die gleiche Zahl an Pixeln einnehmen.3 Das klingt fair, wirkt in der Praxis manchmal aber ungeschickt, wenn Bilder mit mehreren verschiedenen Seitenverhältnissen zusammenkommen. Bilder lassen sich hingegen leicht arrangieren, wenn sie dieselbe Breite oder Höhe aufweisen.
Um eine gewisse Flexibilität zu ermöglichen, entschied ich mich dazu, zwei einfache Vorgaben fürs Vorschaubild auszuwerten: Breite $b_v$ und Höhe $h_v$. Dabei gibt es für jedes der beiden Maße drei Möglichkeiten:
- Ein positiver Wert wie
796
legt das Maß in Pixeln genau fest. - Der Wert
0
steht für keine Vorgabe; das Maß wird automatisch ermittelt. - Ein negativer Wert wie
-796
wird dem Betrag nach als Maximalwert in Pixeln interpretiert, also im Beispiel als „bis zu796
“. Der Maximalwert wird unterschritten, falls das Originalbild kleiner als diese Vorgabe ist oder es dem Erhalt des Seitenverhältnisses dient.
Drei Möglichkeiten für die Breite und drei Möglichkeiten für die Höhe ergeben neun verschiedene Fälle:
$h_v<0$ | $h_v=0$ | $h_v>0$ | |
---|---|---|---|
$b_v<0$ | Fall 4 | Fall 3 | Fall 9 |
$b_v=0$ | Fall 8 | Fall 1 | Fall 7 |
$b_v>0$ | Fall 6 | Fall 2 | Fall 5 |
Formeln
① Weder Breite noch Höhe vorgegeben ($b_v=0, h_v=0$)
Ohne eine Vorgabe zur Breite oder Höhe erhält das neue Bild dieselben Abmaße wie das Original.
Ist es überhaupt sinnvoll, ein Vorschaubild zu erstellen, wenn sich die Maße gegenüber dem Original nicht ändern? Ja, denn das Vorschaubild kann auch dann ein geringeres Datenvolumen umfassen, wenn es stärker komprimiert wird.
② Breite genau vorgegeben, Höhe nicht vorgegeben ($b_v>0, h_v=0$)
Ist die Breite genau vorgegeben, wird sie fürs neue Bild verwendet.
Mithilfe eines Skalierungsfaktors $s$ lässt sich der Zusammenhang von Original- und neuer Breite $b_n=b_o\cdot s$ herstellen. Umgestellt ist der Skalierungsfaktor $s=\frac{b_n}{b_o}$. Den gleichen Skalierungsfaktor nutzen wir fürs Ausrechnen der neuen Höhe $h_n=\left\lfloor h_o\cdot s\right\rceil_+$, sodass das Seitenverhältnis des Originalbildes beim neuen Bild beibehalten wird. Wir runden, da wir es immer mit ganzen Pixeln zu tun haben. Zusammengefasst ergibt das für die neue Höhe
③ Maximalbreite vorgegeben, Höhe nicht vorgegeben ($b_v<0, h_v=0$)
Wenn nur eine Maximalbreite vorgegeben ist, erhält das neue Bild die Breite des Originals, wenn diese den Maximalwert nicht überschreitet. Ansonsten wird der Maximalwert angenommen. Die neue Breite wird also durch den kleineren Wert, dem Minimum aus Originalbreite und vorgegebenem Maximalwert bestimmt.
Da $b_v$ in diesem Fall negativ ist, sorgt das vorgesetzte Minuszeichen für einen positiven Betrag, denn minus mal minus ergibt plus. Wie in ② wird dann für die Höhe der Skalierungsfaktor von der Breite übernommen.
④ Maximalbreite und Maximalhöhe vorgegeben ($b_v<0, h_v<0$)
Wenn Originalbreite und -höhe kleiner als die jeweils vorgegebenen Maximalwerte sind, behält das neue Bild die Maße des Originals: Der Skalierungsfaktor ist dann 1. Anderenfalls wird das Bild und damit der Skalierungsfaktor so weit geschrumpft, bis weder Breite noch Höhe den jeweils vorgegebenen Maximalwert überschreiten.
Je nachdem, ob beim Schrumpfen zuletzt die Maximalbreite oder -höhe eingestellt wird, beträgt der Skalierungsfaktor in jenem Moment $\frac{-b_v}{b_o}$ oder $\frac{-h_v}{h_o}$. Zusammenfassen lässt sich der Skalierungsfaktor als Minimum der drei möglichen Werte
und die neuen Abmaße sind
⑤ Breite und Höhe genau vorgegeben ($b_v>0, h_v>0$)
Bei genau vorgegebener Breite und Höhe ist das Ermitteln der neuen Abmaße kein Hexenwerk.
Wenn das Seitenverhältnis des neuen Bildes nicht dem Original entspricht, kann ohne Verzerrung allerdings nur ein Ausschnitt des Originalbildes ins Vorschaubild übernommen werden.
Die Abmaße des Ausschnitts erhalten wir durchs Skalieren des neuen Bildes
auf die Größe des Originals. Der Skalierungsfaktor $z$ ist dabei
Durch Einsetzen von $z$ sieht man, dass der Ausschnitt entweder die Breite oder die Höhe des Originals annimmt und die andere Seite des Ausschnitts kürzer als am Original ausfällt – eben so, wie es dem Seitenverhältnis des Vorschaubildes entspricht.
⑥ Breite genau vorgegeben, Maximalhöhe vorgegeben ($b_v>0, h_v<0$)
Die genau vorgegebene Breite wird beim neuen Bild berücksichtigt.
Die Höhe des neuen Bildes wird dann genau wie in ② berechnet, solange sie den hier gegebenen Maximalwert nicht überschreitet, der ansonsten verwendet wird.
Damit sind die Abmaße des neuen Bildes ermittelt und der abzubildende Ausschnitt des Originals berechnet sich genau wie bei ⑤.
⑦ Breite nicht vorgegeben, Höhe genau vorgegeben ($b_v=0, h_v>0$)
Wenn man Höhe und Breite vertauscht, gleicht dieser Fall ② und es gilt
⑧ Breite nicht vorgegeben, Maximalhöhe vorgegeben ($b_v=0, h_v<0$)
Wenn man Höhe und Breite vertauscht, gleicht dieser Fall ③ und es gilt
⑨ Maximalbreite vorgegeben, Höhe genau vorgegeben ($b_v<0, h_v>0$)
Wenn man Breite und Höhe vertauscht, gleicht dieser Fall ⑥ und es gilt
Und nun?
Mit den berechneten Maßen kann man ein Programm füttern, welches das Vorschaubild erzeugt. In PHP etwa steht dafür die Funktion „imagecopyresampled“ zur Verfügung.4 Es gibt viele verschiedene Algorithmen zur Größenänderung von Bildern. Wer sich dafür interessiert, wie diese arbeiten, findet eine Reihe von ihnen im Wikipedia-Artikel „Skalierung (Computergrafik)“ in Ansätzen vorgestellt.
- Beispielsweise ist $\min\left\{x,y\right\}=x$ falls $x\leq y$, und $\min\left\{x,y\right\}=y$ falls $x\geq y$.
- Mithilfe des Maximums einer Menge ausgedrückt ist $\lfloor\ldots\rceil_+=\max\left\{\lfloor\ldots\rceil,1\right\}$. Typischerweise macht es beim Erstellen von Vorschaubildern keinen Unterschied, ob $\lfloor\ldots\rceil$ oder $\lfloor\ldots\rceil_+$ verwendet wird. $\lfloor\ldots\rceil_+$ verhindert Divisionen durch null und null Pixel hohe/breite Bilder bei atypischen Vorgaben beziehungsweise Originalen.
- Bei Vorgabe einer Fläche $F_v$ ergäben sich die Maße des Vorschaubildes als $b_n=\left\lfloor b_o\cdot s\right\rceil_+$ und $h_n =\left\lfloor h_o\cdot s\right\rceil_+$ mit dem Skalierungsfaktor $s=\sqrt{\frac{F_v}{b_o\cdot h_o}}$.
- In PHP sähe der Befehl zum Beispiel wie folgt aus:
imagecopyresampled ($vorschau, $original, 0, 0, $x_a, $y_a, $b_n, $h_n, $b_a, $h_a);