Можно ли преобразовать изображение произвольного четырехугольника в прямоугольник заданного размера с помощью 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
Qt/C++ Преобразование четырехугольника (трапеции) в прямоугольник без дополнительных библиотек ⇐ C++
Программы на C++. Форум разработчиков
1716292838
Anonymous
Можно ли преобразовать изображение произвольного четырехугольника в прямоугольник заданного размера с помощью QTransform?
Эта задача доступна для Android: создание прямоугольного растрового изображения из обрезки трапеции
В ответе используется SkMatrix и метод
setPolyToPoly (const Sk Point src[], const SkPoint dst[], int count)
https://github.com/google/skia/blob/main/src/core/SkMatrix.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();
}
Подробнее здесь: [url]https://stackoverflow.com/questions/78511713/qt-c-convert-a-quadrilateral-trapezoid-into-a-rectangle-without-additional-l[/url]
Ответить
1 сообщение
• Страница 1 из 1
Перейти
- Кемерово-IT
- ↳ Javascript
- ↳ C#
- ↳ JAVA
- ↳ Elasticsearch aggregation
- ↳ Python
- ↳ Php
- ↳ Android
- ↳ Html
- ↳ Jquery
- ↳ C++
- ↳ IOS
- ↳ CSS
- ↳ Excel
- ↳ Linux
- ↳ Apache
- ↳ MySql
- Детский мир
- Для души
- ↳ Музыкальные инструменты даром
- ↳ Печатная продукция даром
- Внешняя красота и здоровье
- ↳ Одежда и обувь для взрослых даром
- ↳ Товары для здоровья
- ↳ Физкультура и спорт
- Техника - даром!
- ↳ Автомобилистам
- ↳ Компьютерная техника
- ↳ Плиты: газовые и электрические
- ↳ Холодильники
- ↳ Стиральные машины
- ↳ Телевизоры
- ↳ Телефоны, смартфоны, плашеты
- ↳ Швейные машинки
- ↳ Прочая электроника и техника
- ↳ Фототехника
- Ремонт и интерьер
- ↳ Стройматериалы, инструмент
- ↳ Мебель и предметы интерьера даром
- ↳ Cантехника
- Другие темы
- ↳ Разное даром
- ↳ Давай меняться!
- ↳ Отдам\возьму за копеечку
- ↳ Работа и подработка в Кемерове
- ↳ Давай с тобой поговорим...
Мобильная версия