Bitmapgröße ändern ohne Stretchdraw (interpoliert)
-
Hallo,
mal ne Frage an die etwas erfahreneren Grafikmenschen: mein Programm kann u.a. Bilder verkleinern (nicht für die Ansicht, sondern als separate Datei). Das Problem: ich benutze Stretchdraw und das sieht irgendwie nicht so toll aus, wie z.B. mit IRFANVIEW oder einem Bildverarbeitungsprogramm gemacht. Ich vermute, dass das daran liegt, dass stretchdraw nicht interpoliert. Hat einer von Euch irgendwie Insiderinfos über stretchdraw bzw. kann mir einer sagen, wie man einen möglichst guten interpolierenden "Bildgrößenveränderer" programmieren müsste?MfG Matthias Peters
-
Da dir die bordeigenen Mittel des BCB nicht gut genug sind ;): verschoben nach "Spiele/Grafik".
-
Spielt Geschwindigkeit eine Rolle?
Wenn ja, dann empfehle ich dir bi-lineare Interpolation.
Wenn nein, dann empfehle ich dir bi-kubische Interpolation.Das Ergebnis einer bi-kubische Interpolation ist geringfügig besser. Es ist aber meistens schwer, den Unterschied zu sehen. In meinem Java-Programm dauert bi-kubische Interpolation allerdings fast um einen Faktor 10 länger, als bi-lineare Interpolation.
-
Hi Gregor,
danke für den Tipp. Die Geschwindigkeit spielt schon eine gewisse Rolle. Ich bin gerade dabei die bilineare Interpolation zu programmieren (glaube ich Ich bin mir nicht ganz sicher, ob das was ich mache wirklich die bilineare Interpolation ist; sie funktioniert so, dass ich aus dem QUellbild die Viererumgebungen der Bildpunkte gewichtet mittele, und zwar an den Positionen, wie sie sich aus dem Zielbild ergeben. Ok, nicht gut erklärt, aber jemand der die Methode kennt, wird verstehen was ich meine. Die bikubische Methode kenn ich nicht, aber ich kann ja mal mit google gucken, ob ich irgendwo eine Erklärung dafür finde. Oder hast Du irgendwo einen Link?MfG Matthias
-
Bi-Lineare Interpolation in Java :
[java]
public final int interpolate (final int[] values, final int width,
final int height, final float xValue,
final float yValue)
{
final int minX = MyMath.floor (xValue);
final int minY = MyMath.floor (yValue);
final float dx = xValue - minX;
final float dy = yValue - minY;
float value = getValue (values,width,height,minX,minY) * (1.0f-dx)(1.0f-dy);
value += getValue (values,width,height,minX+1,minY) * dx(1.0f-dy);
value += getValue (values,width,height,minX,minY+1) * (1.0f-dx)dy;
value += getValue (values,width,height,minX+1,minY+1) * dxdy;
return MyMath.round (value);
}private static float getValue (final int [] values, final int width,
final int height, final int x,
final int y)
{
if ((x < 0) || (x >= width) || (y < 0) || (y >= height)) return 0.0f;
return (float)values[y*width+x];
}[/code]
Zur bi-kubischen Interpolation habe ich keinen Link. Die ist auch deutlich komplexer. Kurz zusammengefaßt funktioniert die so :Man betrachtet die 4*4 umliegenden Pixel und bestimmt das bi-kubische Polynom, welches durch alle diese Punkte geht. Der Wert des zu interpolierenden Pixels wird dann durch den wert des Polynoms an diesem Punkt bestimmt.
Ich könnte dir da Java-Code zeigen, ist aber schon recht viel. Wahrscheinlich kann man da auch nicht durchblicken, wenn man nicht eh weiß, was da geschieht.
-
Original erstellt von Gregor:
In meinem Java-Programm dauert bi-kubische Interpolation allerdings fast um einen Faktor 10 länger, als bi-lineare Interpolation.Und damit 50mal länger als bi-lineare Interpolation in C++ und 500mal länger als über die GPU ;).
-
Original erstellt von TGGC:
**
Und damit 50mal länger als bi-lineare Interpolation in C++ und 500mal länger als über die GPU ;).**Zumindest nimmt es mein Programm locker mit GIMP auf, was die Geschwindigkeit beim Vergrößern betrifft.
-
Hi Gregor,
danke für Deine Lösung. Ich hab's auch schon selbst so rausgefunden, was mich aber einiges an Nerven gekostet hat (wg. Farbbildverarbeitung etc.). Außerdem habe ich den Fehler begangen, den Datentyp "char" statt "unsigned char" für die Bilddaten zu nehmen; das führt bei der Interpolation zu seltsamen Effekten. 100%ig zufrieden bin ich übrigens mit dem Ergebnis noch nicht. Ich überlege, ob ich nicht vielleicht doch mal die bikubische Variante ausprobieren sollte...MfG Matthias