Моя предыдущая попытка задать этот вопрос была ужасной, и я также добился определенного прогресса, пожалуйста, несите меня, я не собирался повторно спрашивать об этом столько раз , и это не мой стиль.wxPython - изменение размера изображения с событием EVT_SIZE его родительской панели
Вот окончательная версия: я изменяю размер окна, содержащего раскрашенное изображение клиента DC Client и событие 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 клиента. Я хочу обновить область окна до повторного рисования следующего изображения, потому что, если я не получу странные risiduals, и это выглядит плохо. Чтобы исправить это, я попытался использовать dc.Clear, который очищает фон. Тем не менее, делая это при каждом звонке по размеру, так как мне нужно будет заставлять изображение мигать белым миллион раз, в то время как повторная калибровка. как я могу избежать этого?
EDIT -
В ответ на замечание ответ Umyal в - вот это очень упрощенная версия моего приложения. В любом случае я классифицирую мой оконный генератор для изображений, обработчик размера, перемасштабирующий изображения, заставляет изображение мерцать плохо, создавая непривлекательный артефакт. Кроме того, когда другой кадр проходит через приложение, дисплей изображения становится белым, как если бы он был удален.
Я думал как об этом. Я мог бы реализовать средство просмотра изображений, которое, как представляется, имеет вид, который является образом только масштабируется и перерисовывается, когда пользователь позволяет перейти к краю рамки при его изменении. Проблема с этим решением заключается в том, что нет четкого способа обнаружить, когда пользователь перестает изменять размер кадра. (wxEVT_SIZE, wxEVT_SIZING)
Вот упрощенный код приложения, вам нужно будет найти свои собственные изображения, и чем больше, тем лучше. Оригинальные габариты изображения являются 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()
Это плохой совет по нескольким причинам. Во-первых, мой способ сделать это не мог быть «абсолютно неправильным», потому что после некоторого тестирования я обнаружил, что он действительно намного лучше, чем код, который вы предоставили. Во-вторых, в нем не рассматриваются проблемы, о которых я упоминаю, а именно, что событие размера и перерисовка постоянно заставляют изображение мерцать, что отрицательно сказывается на стороне. Кроме того, изображение по-прежнему становится белым, когда другой кадр проходит над ним. Зачем? Спасибо за внимание, но мне нужен кто-то, кто будет говорить с вопросами, а не мелкие детали реализации. –
Извините за мой выбор слов, но только место для рисования окна - onpaint, чтобы избежать мерцания переопределения EVT_BACKGROUND ничего не делать и использовать двойную буферизацию на EVT_PAINT –
и можете ли вы привести пример, который я могу просто скопировать-вставить и запустить, поэтому что я вижу, с какими проблемами вы сталкиваетесь. –