QImage
に特定の変換を適用したいと思います。性能上の制限があるため、可能であればこれらの変換を適用したいと思います。QPainterでのQTransformの適用 - 翻訳の検索方法
必要な変換 - 90度、180度、270度、および垂直ミラーを回転させる。
QGraphicsScene
をQImage
にレンダリングしています。
結果を回転(0/90/180/270)するか、垂直方向にミラーリングしたいと思います。
私の元のコードは簡単だった:
QImage image = QImage(wOutput, hOutput, QImage::Format_Mono);
image.fill(QColor(Qt::white).rgb());
QPainter painter;
painter.begin(&image);
outputScene->render(&painter);
painter.end();
回転させるには、私は絵の前にQPainter
を回転させるのに効果があるだろうと思った - 私は、追加の変換を実行する必要はありませんその方法は、プロセスを投稿してください。 (私は非常に制限されたメモリとスピードを持つデバイス、Qt4.8を予定しています)
それはうまくいくはずです...しかし回転に加えて、私は翻訳を追加する必要があります。
翻訳なし空白の画像しか取得できません。
また、90/-90に回転すると、より小さい画像が得られます。だから、私はどれくらいスケールする必要がありますか?
変換しようとする私のコード(回転ミラー)イメージ:上記のコードで
#include <QApplication>
#include <QGraphicsScene>
#include <QImage>
#include <QPainter>
#include <QTransform>
QImage processScene(QGraphicsScene *s, int orientation, bool mirror);
QImage otherProcessScene(QGraphicsScene *s, int orientation, bool mirror);
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QGraphicsScene* s = new QGraphicsScene(-20, -100, 800, 600);
s->addText("abcd", QFont("Arial", 20));
s->setBackgroundBrush(Qt::red);
// orientation = -90, 0, 90, 180;
int orientation = -90;
// vertical mirror true/false
bool mirror = true;
// what I am trying to do
QImage im = processScene(s, orientation, mirror);
im.save("test.bmp");
// what I would like to come out like (Qt version)
QImage im1 = otherProcessScene(s, orientation, mirror);
im1.save("test1.bmp");
a.exit();
return 0;
}
QImage processScene(QGraphicsScene* s, int orientation, bool mirror)
{
int wOutput = s->width(), hOutput = s->height();
// translation
int wTr = wOutput, hTr = hOutput;
// coefficients of transformation matrix
qreal m11 = 1, m12 = 0, m21 = 0, m22 = 1, m31 = 0, m32 = 0;
switch(orientation)
{
//case 0: break;
case -90: wTr = hOutput; hTr = wOutput; m11 = 0; m12 = -1; m21 = 1; m22 = 0;
m31 = x?; m32 = x?; break;
case 180: wTr = wOutput; hTr = hOutput; m11 = -1, m22 = -1;
m31 = x?; m32 = x?; break;
case 90: wTr = hOutput; hTr = wOutput; m11 = 0; m12 = 1; m21 = -1; m22 = 0;
m31 = x?; m32 = x?; break;
}
QImage image = QImage(wTr, hTr, QImage::Format_ARGB32_Premultiplied);
image.fill(QColor(Qt::white).rgb());
QPainter painter;
painter.begin(&image);
QTransform painterTransform;
if(mirror)
{
// I have seen that negative scaling actually flips
m22 *= -1;
// I am guessing on shifts...
switch(orientation)
{
case 0: m31 = x?; m32 = x?; break;
case 180: m31 = x?; m32 = x?; break;
case 90: m31 = x?; m32 = x?; break;
case -90: m31 = x?; m32 = x?; break;
}
}
painterTransform.setMatrix(m11, m12, 0, m21, m22, 0, m31, m32, 1);
painter.setTransform(painterTransform);
s->render(&painter);
painter.end();
return image;
}
QImage otherProcessScene(QGraphicsScene *s, int orientation, bool mirror)
{
int wOutput = s->width(), hOutput = s->height();
QImage image = QImage(wOutput, hOutput, QImage::Format_ARGB32_Premultiplied);
image.fill(QColor(Qt::white).rgb());
QPainter painter;
painter.begin(&image);
s->render(&painter);
painter.end();
if(mirror)
image = image.mirrored(0, 1);
image = image.transformed(QMatrix().rotate(orientation));
return image;
}
注 - 私は2つの機能があります
を - 私はQPainter
を回転させることで、やろうとしていますどのようなレンダリング前に
- イメージピクセルを繰り返してイメージをレンダリングした後にQtを "変換"するもの - 非常に大きなイメージの場合、メモリやCPUの限られたデバイスでは非常に遅いです。私がコードで言ったように動作し、それは受け入れられません。
180/90/-90を回転させると、変換とスケーリングの式を計算できませんでした(90/-90は結果が小さいと思われるため)。
ミラーについては、-1でサイズを変更することを願っていますが、シフトを決定するのと同じ問題があります。
シフトが正しくないと、白い画像が表示されます。これを動作させると、90/-90の回転は小さな画像になります(より大きいサイズを小さくし、縦横比を維持する)。
これらの変換を実行する方法を理解してください。私は、角度に基づいて画像を同じサイズに戻すための変換(およびスケーリング)を決定する行列を愛するでしょう - ちょうどこれらの奇妙な角度ではありません。
愚かな質問かもしれませんが、2番目の関数でレンダリングする前に画像を変換することはできませんか? – ymoreau
@ymoreau - レンダリングの前に画像がありません。私は画像を変換したくないので、私は第2の関数を使いたくありません。つまり、ポイント全体の画像変換が各ピクセルを反復処理します。非常に大きな画像と小さなメモリ/ CPUデバイスには非常に時間がかかります。私は仕事がなければ結果を欲しい。 – Thalia