表示状態のビジュアルアイテムに対して Item.grabToImage() を呼び出して表示内容を画像ファイルに保存できます。二つの仮引数があり第一仮引数にはコールバック関数を以下のように指定して画像ファイルを保存します
visualItem.grabToImage(function(result) {
if (!result.saveToFile("imageFileName.png")) {
// 保存できなかったときの処理
}
});
コールバック関数の第二仮引数には保存する画像ファイルのサイズを指定します。省略するとビジュアルオブジェクトのサイズが使われます。HiDPI の場合には描画内容を縮小して画像ファイルに保存されるため、細い線が欠けたりテキストが粗く表示されてしまいます。コールバック関数の第二仮引数にビジュアルオブジェクトのサイズを Screen.devicePixelRatio 倍したサイズを指定すると HiDPI での表示内容がそのまま画像ファイルに保存されます。Screen.devicePixelRatio の値が 2 の場合には以下のようになります。
visualItem.grabToImage(function(result) {
if (!result.saveToFile("imageFIleName@2x.png") {
// 保存できなかったときの処理
}
}, Qt.size(2 * visualItem.width, 2 * visualItem.height));
ビジュアルアイテムの表示内容を HiDPI でファイルに保存するサンプルコードです。
grabtoimage.qml:
import QtQuick 2.12
import QtQuick.Controls 2.12
import QtQuick.Window 2.12
import QtQuick.Layouts 1.12
ApplicationWindow {
visible: true
minimumWidth: 300
minimumHeight: 300
Rectangle {
id: yellowRect
width: 200
height: 200
anchors.centerIn: parent
color: "yellow"
border {
color: "grey"
width: 1/Screen.devicePixelRatio
pixelAligned: Screen.devicePixelRatio > 1 ? false : true
}
Text {
id: messageText
anchors.centerIn: parent
text: "Yellow"
font.pointSize: 20
}
}
MouseArea {
anchors.fill: yellowRect
onClicked: {
if (Screen.devicePixelRatio > 1) {
yellowRect.grabToImage(function(result) {
result.saveToFile(`YellowRectangle@${Screen.devicePixelRatio}x.png`);
}, Qt.size(Screen.devicePixelRatio * yellowRect.width, Screen.devicePixelRatio * yellowRect.height));
} else {
yellowRect.grabToImage(function(result) {
result.saveToFile("YellowRectangle.png");
});
}
}
}
}
Rectangle QML タイプのプロパティー
color: color = "#ffffffff"
gradient: Gradient = null
border: QQuickPen(this) readonly constant
width: real = 1.0
color: color = "#ff000000"
pixelAligned: bool = true
radius: real = 0.0
HiDPI での確認のために Text も表示しています。
Image QML タイプで HiDPI 画像を表示するには以下のように画像ファイルを用意します。前述のサンプルコードでもこのファイル名命名規則に従ってます。
imageFileName.png Screen.devicePixelRatio が 1 用、通常サイズ
imageFileName@2x.png 〃 2 用、サイズ 2 倍
imageFileName@3x.png 〃 3 用、サイズ 3 倍
Image {
source: "YellowRectangle.png"
}
QT_HIGHDPI_DISABLE_2X_IMAGE_LOADING=1
いくつか制約があります。
- ビジュアルアイテムが表示状態の時に Item.grabToImage() で画像保存できます。
- ApplicationWindow の contentItem に設定されているのは Item を継承したビジュアルタイプですが Window が直接そのインスタンスを生成し、QQmlEngine と QQmlContext が紐づけられていないため Item.grabToImage() を使用できません。ApplicationWindow や Window のウィンドウ領域全体に対して Item.grabToImage() を使うにはルートアイテムを contentItem と同じ大きさにします。
- QQuickImageProvider で生成した画像は Image で HiDPI 表示できません。Image が QQuickImageProvider の場合には HiDPI 表示できるようにまだ実装されていないためです。
- ネットワークアクセスした画像は Image で HiDPI 表示できません。