2012-01-20 14 views
1

にロードされたTIFF画像のズームに問題があります。QGraphicsPixmapItemです。画像をスワップするときのQGraphicsViewのビュー/スクロール位置の維持

問題は、アプリケーションのチョークを作らないズームスピードを持つと同時に画質を維持することです。まず最初に、画像を置き換えたのは、QPixmapです。ユーザーが水平スライダーを押している間にQt.FastTransformationを使用し、スライダーを離したときに、Qt.SmoothTransformationを使用してもう一度pixmapを置き換えました。これは素晴らしい質のズームされた画像を与えましたが、画像サイズが元のサイズよりも大きくなるようになった後にズーキーがかかりました。画像のズームアウトは問題ありませんでした。

QGraphicsViewでQTransform.fromScale()を使用すると、QGraphicsViewに.setRenderHints(QPainter.Antialiasing | QPainter.SmoothPixmapTransform | QPainter.HighQualityAntialiasing)を適用しても、はるかにスムーズなズームが可能ですが、低品質の画像が得られます。

最新の方法は、QTransformQGraphicsViewに使用してスムーズにズームすることですが、ユーザーがスライダーを放してQGraphicsViewの画像を拡大縮小したピックスマップで置き換えることです。これは素晴らしいですが、ビュー内の位置は失われます。ユーザーは1つの領域にズームインし、拡大されたピクスマップが大きいので、スライダが解放され、以前の画像に高品質の拡大縮小されたピックスマップが置き換えられます。

どちらの画像でも幅の高さの比率が同じであるため、画像スワップの前にスクロールバーの割合をとり、スワップ後に同じ割合を適用するとうまくいくはずです。これは主にうまくいきますが、画像を交換した後にビューが「ジャンプ」するときがあります。

私はここでかなり間違っていると確信しています。誰かがこれを行うためのより良い方法を知っていますか、誰かがこのジャンプを引き起こす可能性のある以下のコードで何かを見つけることができますか?

これは、スクロールバーの場所を保存/復元するためのコードです。彼らは、サブクラス化QGraphicsViewのメソッドです:

def store_scrollbar_position(self): 
    x_max = self.horizontalScrollBar().maximum() 
    if x_max: 
     x = self.horizontalScrollBar().sliderPosition() 
     self.scroll_x_percentage = x * (100/float(x_max)) 

    y_max = self.verticalScrollBar().maximum() 
    if y_max: 
     y = self.verticalScrollBar().sliderPosition() 
     self.scroll_y_percentage = y * (100/float(y_max)) 


def restore_scrollbar_position(self): 
    x_max = self.horizontalScrollBar().maximum() 
    if self.scroll_x_percentage and x_max: 
     x = x_max * (float(self.scroll_x_percentage)/100) 
     self.horizontalScrollBar().setSliderPosition(x) 

    y_max = self.verticalScrollBar().maximum() 
    if self.scroll_y_percentage and y_max: 
     y = y_max * (float(self.scroll_y_percentage)/100) 
     self.verticalScrollBar().setSliderPosition(y) 

そして、ここでは、私はスケーリングをやっている方法です。 self.imageFileQPixmapself.imageは私のQGraphicsPixmapItemです。再び、サブクラスの一部はQGraphicsViewです。このメソッドは、highQualityパラメータがFalseに設定された状態でスライダの動きに関連付けられます。画像を交換するために、highQualityとしてTrueとスライダリリースで再度呼び出されます。

def setImageScale(self, scale=None, highQuality=True): 
    if self.imageFile.isNull(): 
     return 
    if scale is None: 
     scale = self.scale 
    self.scale = scale 

    self.image.setPixmap(self.imageFile) 
    self.scene.setSceneRect(self.image.boundingRect()) 
    self.image.setPos(0, 0) 
    if not highQuality: 
     self.setTransform(QTransform.fromScale(self.scaleFactor, self.scaleFactor)) 
     self.store_scrollbar_position() 
    else: 
     self.image.setPixmap(self.imageFile.scaled(self.scaleFactor * self.imageFile.size(), 
                Qt.KeepAspectRatio, Qt.SmoothTransformation)) 
     self.setTransform(self.transform) 
     self.scene.setSceneRect(self.image.boundingRect()) 
     self.image.setPos(0, 0) 
     self.restore_scrollbar_position() 
    return 

助けていただければ幸いです。私は今これでかなり不満を持ち始めている。

答えて

1

最初に投稿したコードよりも優れたソリューションが見つかりました。それはまだ完全ではありませんが、はるかに改善されています。念のために誰にも同様の問題を解決しようとしている...

私は、このメソッドを呼び出し、低品質の画像を設定

は私QGraphicsViewに追加:

def get_scroll_state(self): 
    """ 
    Returns a tuple of scene extents percentages. 
    """ 
    centerPoint = self.mapToScene(self.viewport().width()/2, 
            self.viewport().height()/2) 
    sceneRect = self.sceneRect() 
    centerWidth = centerPoint.x() - sceneRect.left() 
    centerHeight = centerPoint.y() - sceneRect.top() 
    sceneWidth = sceneRect.width() 
    sceneHeight = sceneRect.height() 

    sceneWidthPercent = centerWidth/sceneWidth if sceneWidth != 0 else 0 
    sceneHeightPercent = centerHeight/sceneHeight if sceneHeight != 0 else 0 
    return sceneWidthPercent, sceneHeightPercent 

。これはself.scroll_stateに保存されます。高画質画像を設定するときは、前の関数で使用されたパーセンテージを復元する別の関数を呼び出します。

def set_scroll_state(self, scroll_state): 
    sceneWidthPercent, sceneHeightPercent = scroll_state 
    x = (sceneWidthPercent * self.sceneRect().width() + 
     self.sceneRect().left()) 
    y = (sceneHeightPercent * self.sceneRect().height() + 
     self.sceneRect().top()) 
    self.centerOn(x, y) 

これは、画像を交換する前と同じ位置(パーセンテージ)に中心位置を設定します。

関連する問題