Приложение на WF для обработки изображения
Есть программа, выполняет функцию дешёвого фотошопа, создаётся в учебных целях. Моё задание - создать фильтр, который сужает картинку(Bitmap, если что), всё это в обёртке ООП.
public Point? MapPoint(Point point)
{
point = new Point(point.X - ResultSize.Width / 2, point.Y);
var percent = CuttedPart / 100;
var y = (int)(point.Y);
percent += (1 - percent) * (point.Y / (double)ResultSize.Height);
var x = ResultSize.Width / 2 + (int)(point.X / percent);
if (x < 0 || x > originalSize.Width - 1)
return null;
return new Point(x, y);
}
Код выполняет свою задачу, однако, делает это он не правильно. 
Правильный вариант выглядит как-то так
Вопрос, что нужно изменить в математике, чтобы заработало так, как мне надо? Все вычисления и все переменные находятся в одном этом фрагменте, так что и проблема где-то в нём.
Вызывающий код.
mainForm.AddFilter(new TransformFilter<ReversePerspectiveParameters>(
"Сужение нижней части",
new ReversePerspectiveTransformer()));
Код вызывающий метод MapPoint
public override Photo Process(Photo original, TParameters parameters)
{
var oldSize = new Size(original.Width, original.Height);
transformer.Initialize(oldSize, parameters);
var result = new Photo(transformer.ResultSize.Width, transformer.ResultSize.Height);
for(var x = 0; x < result.Width; x++)
for(var y = 0; y < result.Height; y++)
{
var oldPoint = transformer.MapPoint(new Point(x, y));
if(oldPoint.HasValue)
result[x, y] = original[oldPoint.Value.X, oldPoint.Value.Y];
}
return result;
}
Ответы (2 шт):
Автор решения: aepot
→ Ссылка
Примерно так получается. При условии что это System.Drawing.Point.
public Point? MapPoint(Point point)
{
float x = point.X;
float y = point.Y;
float progress = 1.0f - y / ResultSize.Height;
float lineZoom = 100.0f / (100.0f - CuttedPart + CuttedPart * progress);
x = x * lineZoom + ResultSize.Width * (1.0f - lineZoom) / 2.0f;
if (x < 0 || x > originalSize.Width - 1)
return null;
return new Point((int)x, (int)y);
}
Автор решения: SmorcIRL
→ Ссылка
Вот как-то так можно:
static Bitmap Func(Bitmap orig)
{
int w = orig.Width;
int h = orig.Height;
var res = new Bitmap(w, h);
const double percent = 0.3;
int skip = (int) (w * (1 - percent));
for (int i = h - 1; i >= 0; i--, skip--)
{
int take = w - skip;
double step = (double) w / take;
for (int j = 0; j < take ; j++)
{
res.SetPixel(skip / 2 + j, i, orig.GetPixel((int) Clamp(j * step, 0, w - 1), i));
}
}
return res;
}
static double Clamp(double val, double min, double max)
{
return val > max ? max : val < min ? min : val;
}
