#c# #image #rotation
#c# #изображение #вращение #поворот
Вопрос:
мой лектор потребовал, чтобы я написал программу, которая может поворачивать изображение без каких-либо функций преобразования, предоставляемых библиотекой C #, это означает, что я просто мог использовать метод, который предоставляется по ссылке this wiki . Моя проблема в том, что после поворота качество изображения стало очень плохим, как показано на рисунке ниже.
И вот мой код, первая часть — создание нового растрового изображения для изображения после поворота:
double sin = Math.Abs(Math.Sin(ratio * (Math.PI / 180.0)));
double cos = Math.Abs(Math.Cos(ratio * (Math.PI / 180.0)));
bmpOut = new Bitmap((int)(sin * bmpIn.Width cos * bmpIn.Height), (int)(sin * bmpIn.Height cos * bmpIn.Width));
И вот код, который поворачивает изображение
int intHeight = bitmapOri.Height;
int intWidth = bitmapOri.Width;
double x_cen = intWidth / 2.0;
double y_cen = intHeight / 2.0;
unsafe
{
for (int j = 0; j < intWidth; j )
{
for (int i = 0; i < intHeight; i )
{
double x_new = x_cen (double)((j - x_cen) * Math.Cos(ratio) - (i - y_cen) * Math.Sin(ratio));
double y_new = y_cen (double)((j - x_cen) * Math.Sin(ratio) (i - y_cen) * Math.Cos(ratio));
if (x_new < 0 || y_new < 0 || x_new >= bitmapRes.Width || y_new >= bitmapRes.Height)
continue;
bitmapRes.SetPixel((int)x_new, (int)y_new, bitmapOri.GetPixel(j, i));
}
}
}
Не могли бы вы сказать мне, что такое мошенничество в моем коде, что с ним не так, большое спасибо за вашу помощь.
Комментарии:
1. при повороте необходимо учитывать отношение высоты к ширине. если вы повернете изображение шириной 4 и высотой 3 на 90 градусов без регулировки, вы в конечном итоге превратите 4 в 3 и разложите 3 на 4. так что либо отрегулируйте способ поворота, либо найдите способ повернуть объект, в котором находится изображение, а не само изображение.
2. Корень проблемы в вашем кастинге. Когда вы поворачиваете точку вокруг начала координат, точка в подавляющем большинстве случаев приводит к десятичному числу, но когда вы приводите координаты к (int), вы отбрасываете эту информацию. Это приводит к тому, что некоторые пиксели устанавливаются более одного раза, в то время как другие не устанавливаются вообще. Простым решением является округление, а не усечение, но более надежным решением является ответ ZenWu.
3. В качестве примечания, вы также работаете внутри
unsafe
блока, но ни один из ваших кодов не требует, чтобы это было так.4. Другой вопрос. что происходит с моей функцией поворота, когда изображение не вращается по центру?
Ответ №1:
проблема
операция double to int может привести к тому, что некоторые пиксели будут установлены более одного раза, а некоторые пиксели не будут установлены
решение
попробуйте противоположный способ
- каждый пиксель в повернутом изображении
- вычислите их местоположение в исходном изображении
- если местоположение не является целым числом, усредните его примерно на четыре пикселя по расстоянию
Подробные сведения
как вычислить местоположение в исходном изображении
-
пусть ось поворота равна O, рассматривая точку A как пиксель в целевом изображении
-
OA может быть записан как t * rotate(alpha, OX). OX — это нормализованный вектор, начинающийся с точки O. это означает, что вектор OA можно рассматривать как (или получить) повернутый на альфа-угол от OA, и он может иметь специальную длину (t). И реальное значение OA будет (t * cos (альфа), t * sin (альфа))
-
предположим, что OA был фактически повернут OB, поскольку он находится в целевом изображении, повернутом по сравнению с исходным изображением, поэтому OB можно записать как t * rotate (альфа бета, X). Это означает, что OA была одной операцией поворота, отличной от OB. Это немного странно. Но это правильно и полезно.
-
давайте сделаем настоящую работу сейчас. Фактическое значение OB равно (t * cos (альфа бета), t * sin(альфа бета)).
-
давайте сосредоточимся на координате X, которая равна t * cos (альфа) * sin (бета) t * sin (альфа) t * cos (бета), и вернемся к просмотру OA coordinate. из этого следует, что X (OB) = sin (бета) * X (OA) cos (бета) * Y (OA). Координата Y такая же.
Комментарии:
1. Технический термин для шага 3 — «билинейная интерполяция».
2. Какая формула может помочь мне найти местоположение на исходном изображении на шаге 2?
3. @iamatsundere181 просто обратная функция вашей формулы, попробуйте сами, может быть, так как это упражнение
4. Другой вопрос. что происходит с моей функцией поворота, когда изображение не вращается по центру?
5. @iamatsundere181 Мне так жаль, что я действительно не проверил вашу формулу поворота. Я отредактировал ответ и добавил некоторые подробности о шаге 2. Также упоминался поворот поворота