Hallöchen!
Ich hatte schonmal ein ähnliches Problem welches ich hier beschrieben habe.
Die Ausgangssituation ist ungefähr die gleiche. Allerdings steht mir inzwischen Java 8 zur verfügung und es geht nicht darum ein Bild zu rotieren sondern um die Skalierung von Bildern.
Skalierung mit nearest neighbour war kein großes Problem, jedoch brauche ich auch noch einen Algorithmus der eine bessere Qualität zu Stande bringt. Da habe ich mich für die bilineare Interpolation entschieden.
Als ich danach gesucht habe bin auch auf folgenden Beitrag auf Stackoverflow gestoßen: http://stackoverflow.com/questions/16341167/bilinear-interpolation
Ich habe diesen Algorithmus etwas abgeändert, damit ich ihn auf ein zweidimensionales integer array mit ARGB Farbraum anwenden kann und die Performance etwas optimiert, indem ich so wenig Operationen wie möglich mache.
Ich bekomme dabei auch ein skaliertes Bild raus jedoch sieht das nicht ganz wie das gewünschte Ergebnis aus:
Original:
Skaliert (Faktor 2):
Kann mir jemand sagen wo der Fehler liegt?
Ich hatte schonmal ein ähnliches Problem welches ich hier beschrieben habe.
Die Ausgangssituation ist ungefähr die gleiche. Allerdings steht mir inzwischen Java 8 zur verfügung und es geht nicht darum ein Bild zu rotieren sondern um die Skalierung von Bildern.
Skalierung mit nearest neighbour war kein großes Problem, jedoch brauche ich auch noch einen Algorithmus der eine bessere Qualität zu Stande bringt. Da habe ich mich für die bilineare Interpolation entschieden.
Als ich danach gesucht habe bin auch auf folgenden Beitrag auf Stackoverflow gestoßen: http://stackoverflow.com/questions/16341167/bilinear-interpolation
Ich habe diesen Algorithmus etwas abgeändert, damit ich ihn auf ein zweidimensionales integer array mit ARGB Farbraum anwenden kann und die Performance etwas optimiert, indem ich so wenig Operationen wie möglich mache.
Java:
public static final BiConsumer<int[][], int[][]> SCALE_BILINEAR_INTERPOLATION = (source, target) -> {
int srcWidth = source.length;
int srcHeight = source[0].length;
int targetWidth = target.length;
int targetHeight = target[0].length;
int targetX;
int targetY;
int srcX1;
int srcX2;
int srcY1;
int srcY2;
int pixelA;
int pixelB;
int pixelC;
int pixelD;
float ratioX = (float)srcWidth / (float)targetWidth;
float ratioY = (float)srcHeight / (float)targetHeight;
float diffX;
float diffY;
for(targetX = 0; targetX < targetWidth; targetX++) {
for(targetY = 0; targetY < targetHeight; targetY++) {
srcX1 = (int)(ratioX * targetX);
srcX2 = srcX1 + 1;
srcY1 = (int)(ratioY * targetY);
srcY2 = srcY1 + 1;
diffX = (ratioX * targetX) - srcX1;
diffY = (ratioX * targetY) - srcY1;
pixelA = source[srcX1][srcY1];
pixelB = (srcX2 >= 0 && srcX2 < srcWidth && srcY1 >= 0 && srcY1 < srcHeight) ? source[srcX2][srcY1] : pixelA;
pixelC = (srcX1 >= 0 && srcX1 < srcWidth && srcY2 >= 0 && srcY2 < srcHeight) ? source[srcX1][srcY2] : pixelA;
pixelD = (srcX2 >= 0 && srcX2 < srcWidth && srcY2 >= 0 && srcY2 < srcHeight) ? source[srcX2][srcY2] : pixelA;
target[targetX][targetY] = (((int)(((pixelA >> 24) & 0xFF) * (1 - diffX) * (1 - diffY) + ((pixelB >> 24) & 0xFF) * diffX * (1 - diffY) + ((pixelC >> 24) & 0xFF) * diffY * (1 - diffX) + ((pixelD >> 24)) * (diffX * diffY)) & 0xFF) << 24) | (((int)(((pixelA >> 16) & 0xFF) * (1 - diffX) * (1 - diffY) + ((pixelB >> 16) & 0xFF) * diffX * (1 - diffY) + ((pixelC >> 16) & 0xFF) * diffY * (1 - diffX) + ((pixelD >> 16)) * (diffX * diffY)) & 0xFF) << 16) | (((int)(((pixelA >> 8) & 0xFF) * (1 - diffX) * (1 - diffY) + ((pixelB >> 8) & 0xFF) * diffX * (1 - diffY) + ((pixelC >> 8) & 0xFF) * diffY * (1 - diffX) + ((pixelD >> 8)) * (diffX * diffY)) & 0xFF) << 8) | ((int)((pixelA & 0xFF) * (1 - diffX) * (1 - diffY) + (pixelB & 0xFF) * diffX * (1 - diffY) + (pixelC & 0xFF) * diffY * (1 - diffX) + (pixelD) * (diffX * diffY)) & 0xFF);
}
}
};
Ich bekomme dabei auch ein skaliertes Bild raus jedoch sieht das nicht ganz wie das gewünschte Ergebnis aus:
Original:
Skaliert (Faktor 2):
Kann mir jemand sagen wo der Fehler liegt?