2

この質問をする私の以前の試みはひどいものでした、そして私もある程度の進歩を遂げました、私に耐えてください、私はこれを何度も再質問するつもりはありませんでした、そしてそれは私のスタイルではありません。

最終バージョンは次のとおりです。DCクライアントでペイントされたビットマップを含むウィンドウのサイズを変更し、EVT_SIZEイベントで、ウィンドウを再スケールして(再スケールではなくスケールを使用)、画像を再ペイントしてサイズを変更します。問題は、w / hを計算しているのに、アスペクト比を尊重しているように見えないことです。また、高さが高くなると画像が歪んでしまいます。最後に、別のウィンドウがその上を通過すると、画像は白くなります。これらの問題のいずれかを修正する方法はありますか?私のウィンドウ/画像クラスは以下のとおりです。

class TransactionImage(wx.Window):
    def __init__(self, parent, fname, name):
        wx.Window.__init__(self, parent, name=name)

        self.dc = wx.ClientDC(self)  

        self.load_image(fname)
        cursor = wx.StockCursor(wx.CURSOR_MAGNIFIER)
        self.SetCursor(cursor)

        self.Bind(wx.EVT_SIZE, self.resize_space)


    def load_image(self, image):
        self.image = wx.Image(image, wx.BITMAP_TYPE_JPEG)
        (w, h) = self.image.GetSize()
        self.image_ar = w/h

    def resize_space(self, size):
        (w, h) = self.get_best_size()
        self.s_image = self.image.Scale(w, h)
        self.bitmap = wx.BitmapFromImage(self.s_image)
        self.dc.DrawBitmap(self.bitmap, 0, 0, useMask=False)
        # how can I 'refresh this area to make it 'fit'

    def get_best_size(self):
        (window_width, window_height) = self.GetSizeTuple()
        new_height = window_width / self.image_ar
        new_size = (window_width, new_height)
        return new_size

また、クライアントDCの適切な使用方法を理解するのに苦労しています。次の画像を再描画する前にウィンドウ領域を更新したいのですが、そうしないと奇妙な残骸が発生し、見栄えが悪くなります。これを修正するために、背景をきれいにするdc.Clearを使用してみました。ただし、サイズ変更中に画像を100万回白く点滅させる必要があるため、すべてのサイズの呼び出しでこれを行います。どうすればこれを回避できますか?

編集 -

Umyalのコメント応答に応えて、これは私のアプリケーションの非常に単純化されたバージョンです。いずれにせよ、ウィンドウジェネレーターを画像用に分類すると、サイズハンドラーが画像を再スケーリングすると、画像がひどくちらつき、魅力のないアーティファクトが作成されます。また、別のフレームがアプリケーションを通過すると、画像表示は消去されたかのように白くなります。

私はこれを回避する方法として考えていました-ユーザーがフレームのサイズを変更するときにフレームの端から手を離したときにのみ画像が再スケーリングおよび再描画されるという、Windowsイメージビューアが持つと思われるソリューションを実装できました。このソリューションの問題は、ユーザーがフレームのサイズ変更を停止したことを検出する明確な方法がないことです。(wxEVT_SIZE、wxEVT_SIZING)

これが簡略化されたアプリケーションコードです。独自の画像を見つける必要があり、大きいほど良いです。元の画像の寸法は3872x2592です

# this is required for 'real' math - derive the 'aspect ratio'
from __future__ import division
import wx

class TransactionImage(wx.Window):
    def __init__(self, parent, fname, name):
        wx.Window.__init__(self, parent, name=name)

        self.load_image(fname)
        cursor = wx.StockCursor(wx.CURSOR_MAGNIFIER)
        self.SetCursor(cursor)

        self.Bind(wx.EVT_SIZE, self.resize_space)
        self.Bind(wx.EVT_PAINT, self.on_paint)

    def load_image(self, image):
        self.image = wx.Image(image, wx.BITMAP_TYPE_JPEG)
        (w, h) = self.image.GetSize()
        self.image_ar = w/h
        self.bitmap = wx.BitmapFromImage(self.image)

    def resize_space(self, event):
        (w, h) = self.get_best_size()
        self.s_image = self.image.Scale(w, h)
        self.bitmap = wx.BitmapFromImage(self.s_image)

    def on_paint(self, event):
        self.dc = wx.PaintDC(self)
        self.dc.DrawBitmap(self.bitmap, 0, 0, useMask=False)

    def get_best_size(self):
        (window_width, window_height) = self.GetSizeTuple()
        new_height = window_width / self.image_ar
        new_size = (window_width, new_height)
        return new_size


class OriginalTransactionImage(wx.Window):
    def __init__(self, parent, fname, name):
        wx.Window.__init__(self, parent, name=name)

        self.dc = wx.ClientDC(self)  

        self.load_image(fname)
        cursor = wx.StockCursor(wx.CURSOR_MAGNIFIER)
        self.SetCursor(cursor)

        self.Bind(wx.EVT_SIZE, self.resize_space)


    def load_image(self, image):
        self.image = wx.Image(image, wx.BITMAP_TYPE_JPEG)
        (w, h) = self.image.GetSize()
        self.image_ar = w/h

    def resize_space(self, size):
        (w, h) = self.get_best_size()
        self.s_image = self.image.Scale(w, h)
        self.bitmap = wx.BitmapFromImage(self.s_image)
        self.dc.DrawBitmap(self.bitmap, 0, 0, useMask=False)

    def get_best_size(self):
        (window_width, window_height) = self.GetSizeTuple()
        new_height = window_width / self.image_ar
        new_size = (window_width, new_height)
        return new_size


class ImageBrowser(wx.Frame):

    def __init__(self, image1, image2, parent=None, id=wx.ID_ANY,
                 pos=wx.DefaultPosition, title='Image Browser'):
        size = (1500, 800)
        wx.Frame.__init__(self, parent, id, title, pos, size)

        self.CentreOnScreen()

        self.panel = wx.Panel(self, wx.ID_ANY)
        self.panel.SetBackgroundColour(wx.Colour(191,197,229))

        self.main_sizer = wx.BoxSizer(wx.VERTICAL)

        self.image_panel = wx.Panel(self.panel, wx.ID_ANY, style=wx.SIMPLE_BORDER)
        self.image_panel.SetBackgroundColour(wx.Colour(255, 255, 255))

        self.image_sizer = wx.BoxSizer(wx.HORIZONTAL)
        self.image_panel.SetSizer(self.image_sizer)

        self.load_image_sizer(image1, image2)
        self.main_sizer.Add(self.image_panel, 1, wx.GROW|wx.ALIGN_CENTER|wx.ALL, 25)
        self.panel.SetSizer(self.main_sizer)


    def load_image_sizer(self, image1, image2):
        #bitmap1 = OriginalTransactionImage(self.image_panel, image1, 'image1')
        #bitmap2 = OriginalTransactionImage(self.image_panel, image2, 'image2')

        bitmap1 = TransactionImage(self.image_panel, image1, 'image1')
        bitmap2 = TransactionImage(self.image_panel, image2, 'image2')

        self.image_sizer.Add(bitmap1, 1, wx.GROW|wx.ALIGN_LEFT|wx.ALL, 20)
        self.image_sizer.Add(bitmap2, 1, wx.GROW|wx.ALIGN_RIGHT|wx.ALL, 20)


class IBApp(wx.App):

    def OnInit(self):
        img1 = "0_3126_image1.jpeg"
        img2 = "0_3126_image2.jpeg"

        ib = ImageBrowser(img1, img2)
        ib.Show()
        self.SetTopWindow(ib)        
        return True

app = IBApp(False, None)
app.MainLoop()
4

1 に答える 1

1

ウィンドウインスタンス( http://docs.wxwidgets.org/2.6/wx_wxclientdc.html )にクライアントDCへの参照を保持しないでください。どちらも、ウィンドウDCを描画する適切な方法ではありません。

代わりに、PAINT_EVENTにバインドしてそこに描画します。以下に、あなたが言ったことをクラスに追加する方法を示します。

class TransactionImage(wx.Window):
    def __init__(self, parent, fname, name):

        self.Bind(wx.EVT_SIZE, self.resize_space)
        self.Bind(wx.EVT_PAINT, self.onpaint)

    def onpaint(self):
        dc = wx.PaintDC(self)
        dc.DrawBitmap(self.bitmap, 0, 0, useMask=False)

    def resize_space(self, size):
        (w, h) = self.get_best_size()
        self.s_image = self.image.Scale(w, h)
        self.bitmap = wx.BitmapFromImage(self.s_image)
        self.Refresh()
于 2009-07-21T03:47:42.567 に答える