PySide でズームイン/ズームアウトを実現する


今回は、PySide を使って画像をズームイン/ズームアウトしてみます。このやり方で、画像を拡大/縮小しながら表示するエフェクトが得られます。この記事を読む前に、PySide で画像をスライドさせる | DeVlog – 銀の翼で翔べ – を読んでいただくとより理解しやすいと思います。

今回の記事も Python3.3 で検証しています。

アプリケーションの骨格を作る

まず、いつものようにアプリケーションの骨格を作っておきます。メインウインドウ(window)内に、画像(hoge.jpg)を表示するラベル(label)を表示します。setGeometry のパラメータを必要に応じて調整してください。

実行すると左上角に画像が表示されます。
base

どのようにズームを実現するのか

QLabel には “scaledContents” というプロパティがあります。これを True に設定しておくと、中に格納されたイメージはラベルの大きさと同じになるように拡大/縮小されて(ラベルいっぱいに)表示されます。この特性を使えば、画像そのものを拡大/縮小する操作をしなくても、ラベルの拡大/縮小だけでズームが実現できます。

以下のようにズームアニメーションを取得するメソッドを書けます。target として QLabel オブジェクトを与え、mag1, mag2 に最初と最後のズーム倍率(0 〜 1)を与えます。

setScaledContents(True) で “scaledContents” を True にし、QLabel の “size” プロパティをアニメーション化することでズームを実現します。QSize オブジェクト (mapsize) には ‘*’ 演算が定義(オーバーロード)されているので、倍率を掛け算するだけで新しい QSize オブジェクトが得られます。Python でも演算子のオーバーロードが使えるんですね。

アニメーションを実行するには、アニメーションオブジェクトの start メソッドを実行します。

画像中央を基準にズームするには

先ほどの例では、左上角が固定されてズームされています。画像中央を中心として拡大/縮小していくようなエフェクトについても考えてみます。

画像中央を中心とする場合は、画像が左上のままでははみ出てしまいますので、まず準備として、画像を中央に配置しておきます。
以下のような、親オブジェクト(parent)の中央に、幅 width, 高さ height の画像を配置する場合の “pos” (画像の左上角) を計算するメソッドを作り、

このメソッドを使って画像をウインドウ中央に配置します。

center

それでは、中央固定のズームについて、あらためて考えてみます。左上固定の場合というのは、”pos” が固定しているという事です。”pos” はターゲットの左上角の座標ですから当然といえば当然です。逆に言うと、中央固定の場合、ズームと共に “pos” が変化するという事です。
zoom

つまり、画像のズームと同時に “pos” も変化するアニメーションを作れば良いのです。”pos” を変化させる(画像をスライドさせる)アニメーションについては、すでに PySide で画像をスライドさせる | DeVlog – 銀の翼で翔べ – で解説していますのでそちらも参照してください。

では、最初に “pos” を pos1 から pos2 に変化させるアニメーションを取得するメソッドを定義します。

次に、ターゲットをズームした時の “pos” の位置を計算するメソッドを作っておきます。

そして、ターゲット中央を固定してズームするアニメーションを取得するメソッドを作成します。QParallelAnimationGroup を使うことで、zoom と move を同時に実行します。(QSequentialAnimationGroup を使った例として、PySide で画像をフェードイン/フェードアウト | DeVlog – 銀の翼で翔べ – も参照して下さい。)

このメソッドで返されるアニメーションオブジェクトの start() メソッドを実行すると、このページの最初に示したようなエフェクトが得られます。
なお、完全なコードをこちらに用意しましたので、hoge.jpg を用意して実行してみてください。

[関連サイト]
junf/PySideSamples · GitHub

[関連記事]

  1. PySide で画像をフルスクリーン表示する | DeVlog – 銀の翼で翔べ –
  2. PySide で画像をスライドさせる | DeVlog – 銀の翼で翔べ –
  3. PySide で画像をフェードイン/フェードアウト | DeVlog – 銀の翼で翔べ –

メールアドレスが公開されることはありません。