wxPython的 - 调整图像大小与其父面板的EVT_SIZE事件
-
18-09-2019 - |
题
我以前在问这个问题的尝试是可怕的,我也取得了一些进展,请原谅,我不打算重新问这个了这么多次,这是不是我的风格。
下面是最后的版本:我调整包含DC客户绘位图的窗口,并在EVT_SIZE事件,我对重新缩放它(使用规模,不重新调整),并重新画影像缩放它。问题是,它不会出现,好像在尊重即使我计算瓦特/它小时宽高比。此外,当它生长在高度图像失真。最后,当另一个窗口经过它时,图像变成了白色。任何想法如何解决所有这些问题?我的窗口/图像类低于:
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。我想重新绘制下一个图像之前刷新窗口区域,因为如果我不我得到奇怪的risiduals,它看起来不错。为了解决这个问题我尝试使用dc.Clear用于清洁背景关闭。然而,在各种规模的呼叫这样做,因为我需要使图像闪烁白色百万次,而IM RE-大小。我怎样才能避免这种情况?
编辑 -
在回应Umyal的评论回应 - 这是我的应用程序的一个非常简化的版本。对于大小处理图像无论哪种方式,我类我的窗前,发电机重新缩放图像会导致图像闪烁严重,创造了一个不吸引人的神器。此外,当另一帧经过的应用,所述图像显示变成白色,仿佛被擦除。
我想作为解决的办法 - 我可以实现该解决方案的窗口图像浏览器似乎有,这是图像只重新调整和重新粉刷时,用户可以调整大小,当它去框的边缘。与溶液的问题是,存在当用户停止调整大小的帧,以检测没有明确的方法。 (wxEVT_SIZE,wxEVT_SIZING)
下面是简化应用程序的代码,你需要找到自己的图像和越大越好。原始图像dimentions是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://文档。 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()