Qimageまたはqpixmapを半透明にする方法 - またはなぜSetalphachannelが時代遅れになるのですか?
-
09-10-2019 - |
質問
4.7そして、qgraphicsViewで2つの画像をオーバーレイするのが好きです。上の画像は、それを見ることができるように半透明でなければなりません。最初は両方の画像が完全に不透明です。各ピクセルのグローバルアルファ値を設定するための機能が存在することを期待していましたが、そのような機能はないようです。それに最も近いのはqpixmap :: setalphachannel(const qpixmap&alphachannel)ですが、qt-4.6以来時代遅れとしてマークされています。代わりに、マニュアルはQpainterの構成モードを指しますが、私が望むように不透明な画像に透明性を追加することは成功しません。誰かが私に実用的な例を指したり、コードを共有したりできますか?
編集:質問をしてからほんの数時間後、自分の答えを持っていてごめんなさい。これから 記事 次のコードが仕事をしていることがわかりました。これは、アルファ値をpixelwiseで変更するよりも「より良い」(しばしばより速く変換される)と見なされるのだろうかと思います。
QPainter p;
p.begin(image);
p.setCompositionMode(QPainter::CompositionMode_DestinationIn);
p.fillRect(image->rect(), QColor(0, 0, 0, 120));
p.end();
mpGraphicsView->scene()->addPixmap(QPixmap::fromImage(image->mirrored(false,true),0));
解決
QTの構成デモ 彼らはすべてを見せようとしているので、少し威圧的になる可能性があります。うまくいけば、デモと QPainterドキュメント あなたに役立ちます。 CompositionMode :: sourceoverを使用し、画像がArgb32(premultipried)に変換されていることを確認します。ドキュメントから:
When the paint device is a QImage, the image format must be set to Format_ARGB32Premultiplied or Format_ARGB32 for the composition modes to have any effect. For performance the premultiplied version is the preferred format.
他のヒント
画家のオブジェクトを使用して、不透明度を設定します。
void ClassName::paintEvent(QPaintEvent *event)
{
QPainter painter(this);
painter.setOpacity(1.00); //0.00 = 0%, 1.00 = 100% opacity.
painter.drawPixmap(QPixmap(path));
}
まず、画像の内部操作の場合、QPIXMAPへの直接アクセス機能が制限されているため、QPIXMAPの代わりにQIMAGEを使用する必要があります。その理由は、QPIXMAPがレンダリングデバイスに保存されているためです。たとえば、XサーバーまたはGLテクスチャのPIXMAPなどです。一方、QPIXMAPからQIMAGEに移動することは、グラフィックカードのメモリからメインメモリとバックにコピーすることが多いため、高価です。
私が見るように、ピクセルのアルファ値のみを変更する操作が必要であり、ブリットのために元の値をそのまま残します。エレガントではないが機能する1つの解決策は、次のとおりです。
for (int y = 0; y < image.height() ++y) {
QRgb *row = (QRgb*)image.scanLine(y);
for (int x = 0; x < image.width(); ++x) {
((unsigned char*)&row[x])[3] = alpha;
}
}
注:Qimageの各ピクセルを変更してから実行する方がはるかに速いです painter.drawImage()
対応するアルファで各ピクセルを手で描画するよりも。