Qt/C++ Преобразование четырехугольника (трапеции) в прямоугольник без дополнительных библиотекC++

Программы на C++. Форум разработчиков
Ответить
Anonymous
 Qt/C++ Преобразование четырехугольника (трапеции) в прямоугольник без дополнительных библиотек

Сообщение Anonymous »

Можно ли преобразовать изображение произвольного четырехугольника в прямоугольник заданного размера с помощью QTransform?

Эта задача доступна для Android: создание прямоугольного растрового изображения из обрезки трапеции
В ответе используется SkMatrix и метод
setPolyToPoly (const Sk Point src[], const SkPoint dst[], int count)

https://github.com/google/skia/blob/mai ... Matrix.cpp
который, похоже, формирует матрицу модификаторов над четырехугольником src чтобы потом сделать из него dst четырёхугольник (я так понимаю). Я не нашел подобного метода в QTransform.
Я переписал эти коды на c++ и Qtransform. Я учел, что константы положения в SkMatrix отличаются от QTranform. Но когда я пытаюсь применить QTransform, полученный моей функцией, я получаю на экране непредсказуемый результат. Может быть я ошибся в кодах или неправильно применяю результат?
// SkMatrix Constants
static constexpr int kMScaleX = 0; //!< horizontal scale factor
static constexpr int kMSkewX = 1; //!< horizontal skew factor
static constexpr int kMTransX = 2; //!< horizontal translation
static constexpr int kMSkewY = 3; //!< vertical skew factor
static constexpr int kMScaleY = 4; //!< vertical scale factor
static constexpr int kMTransY = 5; //!< vertical translation
static constexpr int kMPersp0 = 6; //!< input x perspective factor
static constexpr int kMPersp1 = 7; //!< input y perspective factor
static constexpr int kMPersp2 = 8; //!< perspective bias

// Constants for Qt
static constexpr int qtScaleX = 0; // 11 // scale
static constexpr int qtSkewY = 1; // 12 // shear
static constexpr int qtPerspY = 2; // 13 // влияет rotate вокгуг YAxias / = Persp1
static constexpr int qtSkewX = 3; // 21 // shear
static constexpr int qtScaleY = 4; // 22 // scale
static constexpr int qtPerspX = 5; // 23 // влияет rotate вокгуг XAxias / = Persp0
static constexpr int qtTransX = 6; // 31 // translate
static constexpr int qtTransY = 7; // 32 // translate
static constexpr int qtPerspZ = 8; // 33 // не удалось повлиять на значение / = Persp2
/*
ScaleX SkewY PerspY
SkewX ScaleY PerspX
TransX TransY PerspZ
*/

void convertSkToQt(const QTransform& skSrc, QTransform& qtDst)
{
QList skLine(9, 0);
skLine[kMScaleX ] = skSrc.m11();
skLine[kMSkewX ] = skSrc.m21();
skLine[kMTransX ] = skSrc.m31();
skLine[kMSkewY ] = skSrc.m12();
skLine[kMScaleY ] = skSrc.m22();
skLine[kMTransY ] = skSrc.m32();
skLine[kMPersp0 ] = skSrc.m23();
skLine[kMPersp1 ] = skSrc.m13();
skLine[kMPersp2 ] = skSrc.m33();

/*
ScaleX SkewY PerspY
SkewX ScaleY PerspX
TransX TransY PerspZ
*/
qtDst.setMatrix(
skLine[kMScaleX ], skLine[kMSkewY ], skLine[kMPersp1 ]
, skLine[kMSkewX ], skLine[kMScaleY], skLine[kMPersp0 ]
, skLine[kMTransX ], skLine[kMTransY], skLine[kMPersp2 ]
);
}

bool poly4Proc(const QList& srcPt, QTransform& dst) {
qreal a1, a2;
qreal x0, y0, x1, y1, x2, y2;
x0 = srcPt[2].x() - srcPt[0].x();
y0 = srcPt[2].y() - srcPt[0].y();
x1 = srcPt[2].x() - srcPt[1].x();
y1 = srcPt[2].y() - srcPt[1].y();
x2 = srcPt[2].x() - srcPt[3].x();
y2 = srcPt[2].y() - srcPt[3].y();
/* check if abs(x2) > abs(y2) */
if ( x2 > 0 ? y2 > 0 ? x2 > y2 : x2 > -y2 : y2 > 0 ? -x2 > y2 : x2 < y2) {
float denom = sk_ieee_float_divide(x1 * y2, x2) - y1;
if (checkForZero(denom)) {
return false;
}
a1 = (((x0 - x1) * y2 / x2) - y0 + y1) / denom;
} else {
float denom = x1 - sk_ieee_float_divide(y1 * x2, y2);
if (checkForZero(denom)) {
return false;
}
a1 = (x0 - x1 - sk_ieee_float_divide((y0 - y1) * x2, y2)) / denom;
}
/* check if abs(x1) > abs(y1) */
if ( x1 > 0 ? y1 > 0 ? x1 > y1 : x1 > -y1 : y1 > 0 ? -x1 > y1 : x1 < y1) {
float denom = y2 - sk_ieee_float_divide(x2 * y1, x1);
if (checkForZero(denom)) {
return false;
}
a2 = (y0 - y2 - sk_ieee_float_divide((x0 - x2) * y1, x1)) / denom;
} else {
float denom = sk_ieee_float_divide(y2 * x1, y1) - x2;
if (checkForZero(denom)) {
return false;
}
a2 = (sk_ieee_float_divide((y0 - y2) * x1, y1) - x0 + x2) / denom;
}

QList lineMatrix(9, 0);
lineMatrix[kMScaleX] = a2 * srcPt[3].x() + srcPt[3].x() - srcPt[0].x();
lineMatrix[kMSkewY] = a2 * srcPt[3].y() + srcPt[3].y() - srcPt[0].y();
lineMatrix[kMPersp0] = a2;
lineMatrix[kMSkewX] = a1 * srcPt[1].x() + srcPt[1].x() - srcPt[0].x();
lineMatrix[kMScaleY] = a1 * srcPt[1].y() + srcPt[1].y() - srcPt[0].y();
lineMatrix[kMPersp1] = a1;
lineMatrix[kMTransX] = srcPt[0].x();
lineMatrix[kMTransY] = srcPt[0].y();
lineMatrix[kMPersp2] = 1;

dst.setMatrix( lineMatrix[0], lineMatrix[1], lineMatrix[2]
, lineMatrix[3], lineMatrix[4], lineMatrix[5]
, lineMatrix[6], lineMatrix[7], lineMatrix[8]
);

return true;
}

bool setPolyToPoly(QTransform& matrix, const QList& src, const QList& dst)
{
QTransform tempMap, result;
if (!poly4Proc(src, tempMap))
return false;

bool done = false;
result = tempMap.inverted(&done);
if (!done) {
qDebug().noquote() setTransform(polyToPolymatrix);

painter->drawPixmap(QPointF(0, 0), m_pixmap, QRectF(0, 0, 200, 200));

painter->restore();
}


Подробнее здесь: https://stackoverflow.com/questions/785 ... ditional-l
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C++»