Вращение, масштабирование, сдвиг изображений. Работает, но есть баг
Пытался решить задачу вращения, масштабирования и сдвига изображения.
Попробовал, наверное, все, что описано в интернетах. И через pixels, и через scanline, а теперь вот SetWorldTransform.
Самым быстрым способом похоже является SetWorldTransform. К тому же он освобождает от самостоятельного закрашивания пробелов, которые образуются при повороте.
Получился пока вот такой код:
Вызов функции:
Код:
rotate_move_scale( bug1->Picture->Bitmap, bug2->Picture->Bitmap, back->Picture->Bitmap, Form1->horizontal_scale->Position / 100.0 , Form1->vertical_scale->Position / 100.0, angle);
Код:
void rotate_move_scale( TBitmap * source, TBitmap * middle, TBitmap *dest, float x_aspect, float y_aspect, float new_angle)
//поворот
{
//TBitmap *middle = new TBitmap; //промежуточное изображение для масштабирования
middle->Width = source->Width * x_aspect; //увеличиваем размер промежуточного изображения
middle->Height = source->Height * y_aspect; //увеличиваем размер промежуточного изображения
HDC dc; //указатель на handler
XFORM xform;
//масштаб на промежуточном битмапе
dc = middle->Canvas->Handle; //где будем менять законы отрисовки
middle->Canvas->FillRect(Rect(0,0,middle->Width,middle->Height)); //затираем канвас
xform.eDx = 0.0f;
xform.eDy = 0.0f;
xform.eM11 = x_aspect; //масштаб по горизонтали
xform.eM12 = 0.0f;
xform.eM21 = 0.0f;
xform.eM22 = y_aspect; //масштаб по вертикали
SetGraphicsMode(dc, GM_ADVANCED);
SetWorldTransform(dc, &xform);
middle->Canvas->Draw(0,0,source); //рисуем отмасштабированный результат
//поворот и сдвиг на итоговый битмап
dc = dest->Canvas->Handle; //где будем менять законы отрисовки
dest->Canvas->FillRect(Rect(0,0,dest->Width,dest->Height)); //затираем канвас
new_angle = new_angle * 3.1416 / 180.0; //перевод в радианы
xform.eDx = Form1->horizontal_move->Position; //смещение по горизонтали
xform.eDy = Form1->vertical_move->Position; //смещение по вертикали
xform.eM11 = cos(new_angle);
xform.eM12 = sin(new_angle);
xform.eM21 = -sin(new_angle);
xform.eM22 = cos(new_angle);
SetGraphicsMode(dc, GM_ADVANCED);
SetWorldTransform(dc, &xform);
dest->Canvas->Draw(0,0,middle); //рисуем повернутый и сдвинутый результат
// delete middle;
}
//поворот
{
//TBitmap *middle = new TBitmap; //промежуточное изображение для масштабирования
middle->Width = source->Width * x_aspect; //увеличиваем размер промежуточного изображения
middle->Height = source->Height * y_aspect; //увеличиваем размер промежуточного изображения
HDC dc; //указатель на handler
XFORM xform;
//масштаб на промежуточном битмапе
dc = middle->Canvas->Handle; //где будем менять законы отрисовки
middle->Canvas->FillRect(Rect(0,0,middle->Width,middle->Height)); //затираем канвас
xform.eDx = 0.0f;
xform.eDy = 0.0f;
xform.eM11 = x_aspect; //масштаб по горизонтали
xform.eM12 = 0.0f;
xform.eM21 = 0.0f;
xform.eM22 = y_aspect; //масштаб по вертикали
SetGraphicsMode(dc, GM_ADVANCED);
SetWorldTransform(dc, &xform);
middle->Canvas->Draw(0,0,source); //рисуем отмасштабированный результат
//поворот и сдвиг на итоговый битмап
dc = dest->Canvas->Handle; //где будем менять законы отрисовки
dest->Canvas->FillRect(Rect(0,0,dest->Width,dest->Height)); //затираем канвас
new_angle = new_angle * 3.1416 / 180.0; //перевод в радианы
xform.eDx = Form1->horizontal_move->Position; //смещение по горизонтали
xform.eDy = Form1->vertical_move->Position; //смещение по вертикали
xform.eM11 = cos(new_angle);
xform.eM12 = sin(new_angle);
xform.eM21 = -sin(new_angle);
xform.eM22 = cos(new_angle);
SetGraphicsMode(dc, GM_ADVANCED);
SetWorldTransform(dc, &xform);
dest->Canvas->Draw(0,0,middle); //рисуем повернутый и сдвинутый результат
// delete middle;
}
По итогу, вроде бы все работает, но при переносе изображения из промежуточного на итоговое, что то происходит с маштабированием. При увеличении масштаба, размер изображения на итоговой картинке не меняется. А при уменьшении - срезается часть изображения.
При этом на промежуточном этапе видно, что масштабирование работает правильно.
Может кто подскажет, что я делаю не так ?