У меня есть алгоритм билинейной интерполяции, но он немного отличается от алгоритма, реализованного в редакторе изображений.
Результат при изменении размера с помощью Paint.NET:

Результат при изменении размера по приведенному ниже алгоритму:

Код, который вызывается для каждой строки/столбца в target:
public static void ResizeBiLinear(источник матрицы, цель матрицы, int row, int col) { вар TX = столбец; вар ты = строка; вар sx = tx * source.W/target.W; var sy = ty * source.H / target.H; var lx = (float)tx * source.W / target.W - sx; var ly = (float)ty * source.H / target.H - sy; вар f00 = source.GetValue(sx + 0, sy + 0); вар f01 = source.GetValue(sx + 0, sy + 1); var f10 = source.GetValue(sx + 1, sy + 0); вар f11 = source.GetValue(sx + 1, sy + 1); var a = float.Lerp(f00, f10, lx); var b = float.Lerp(f01, f11, lx); вар c = float.Lerp(a, b, ly); цель [строка, столбец] = с; } Код для source.GetValue(...):
public float GetValue(int x, int y, MatrixWrapMode xMode = MatrixWrapMode.Clamp, MatrixWrapMode yMode = MatrixWrapMode.Clamp) { var x1 = переключатель xMode { MatrixWrapMode.Clamp => Math.Clamp(x, 0, W - 1), MatrixWrapMode.Repeat => Mod(x, W), _ => выдать новое исключение ArgumentOutOfRangeException(nameof(xMode), xMode, null) }; var y1 = переключатель режима y { MatrixWrapMode.Clamp => Math.Clamp(y, 0, H - 1), MatrixWrapMode.Repeat => Mod(y, H), _ => выдать новое исключение ArgumentOutOfRangeException(nameof(yMode), yMode, null) }; вар f = F[y1, x1]; вернуть f; статический int Mod(int x, int m) { return (int)(((long)x % m + m) % m); } } Я предполагаю, что 0.5f или 1.0f где-то отсутствует, но я не смог этого понять...
Мобильная версия