문제

이 질문을하려는 나의 이전의 시도는 끔찍했고 나는 또한 약간의 진전을 이루었습니다. 저와 함께하십시오. 나는 이것을 여러 번 다시 할 의도가 없었으며, 그것은 내 스타일이 아닙니다.

최종 버전은 다음과 같습니다. 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를 사용해 보았습니다. 그러나 모든 크기의 호출에서 그렇게하는 동안 이미지가 백만 번 흰색으로 깜박이는 동안 다시 크기를 조정해야합니다. 이것을 피하려면 어떻게해야합니까?

편집하다 -

Umyal의 의견 응답에 대한 응답으로 - 여기 내 응용 프로그램의 매우 단순화 된 버전이 있습니다. 어느 쪽이든 이미지에 대한 창 생성기를 클래스하는 크기 핸들러 이미지를 다시 스케일링하면 이미지가 잘못 깜박 거리며 매력적이지 않은 아티팩트가 생성됩니다. 또한 다른 프레임이 응용 프로그램을 통과하면 지우는 것처럼 이미지 디스플레이가 흰색이됩니다.

나는 이것을 둘러싼 방법으로 생각하고있었습니다 - 나는 Windows 이미지 뷰어가 가지고있는 것처럼 보이는 솔루션을 구현할 수 있습니다. 이것은 이미지가 프레임을 크기를 조정할 때 프레임의 가장자리를 놓을 때만 저장되고 다시 페인트됩니다. 해당 솔루션의 문제점은 사용자가 프레임 크기 조정을 중지 할 때를 감지 할 수있는 명확한 방법이 없다는 것입니다. (wxevt_size, wxevt_sizing)

여기 단순화 된 응용 프로그램 코드는 다음과 같습니다. 자신의 이미지를 찾아야하며 더 커질수록 좋습니다. 원래 이미지 dentions는 3872 x 2592입니다

# 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()
도움이 되었습니까?

해결책

창 인스턴스에서 클라이언트 DC에 대한 참조를 유지하지 마십시오 (http://docs.wxwidgets.org/2.6/wx_wxclientdc.html), 창문 위에 그리는 적절한 방법도 아닙니다.

대신 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()
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top