Качество изображения на wx python ухудшается - PullRequest
0 голосов
/ 13 марта 2019

В моем приложении я разрешаю пользователю изменять размеры определенных изображений. Все изображения читаются при открытии приложения и хранятся в словаре.

Мое решение позволяет изменять размеры, но при изменении масштаба изображения качество ухудшается. Я хотел бы сделать что-то вроде глубокой копии изображения, прежде чем оно будет изменено, но, похоже, я не могу этого достичь.

(я знаю, что код кажется запутанным, но я извлек его из гораздо большего и более сложного набора кода)

Я просто использую любой старый png-файл в качестве источника изображения.

import wx
import copy


class MainFrame(wx.Frame):
    IMAGE_SIZE = ['large', 'medium', 'small']
    IMAGE_NAME = 'question'
    def __init__(self, *args, **kwargs):
        super(MainFrame, self).__init__(None, *args, **kwargs)
        self.Title = 'Test image size'
        self.images = self._get_images()
        self.panel = MainPanel(self)
        sizer = wx.BoxSizer()
        sizer.Add(self.panel)
        self.SetSizerAndFit(sizer)
        self.Centre()
        self.Show()

    def _get_images(self):
        image = wx.Image(self.IMAGE_NAME+'.png')
        return {self.IMAGE_NAME: image}

    def on_image_size_click(self, event):
        size_index = self.panel.image_size.GetSelection()
        image_size = self.IMAGE_SIZE[size_index]
        self.panel.image.refresh(self.IMAGE_NAME, image_size)
        self.Layout()


class MainPanel(wx.Panel):
    def __init__(self, parent, *args, **kwargs):
        super(MainPanel, self).__init__(parent, *args, **kwargs)
        self.images = parent.images
        sizer = wx.BoxSizer(wx.HORIZONTAL)
        self.image_size = wx.RadioBox(parent=self, label='Image_size',
                                      choices=parent.IMAGE_SIZE,
                                      style=wx.RA_SPECIFY_ROWS)
        self.image_size.Bind(wx.EVT_RADIOBOX, parent.on_image_size_click)
        self.image = ImagePanel(self, parent.IMAGE_NAME, parent.IMAGE_SIZE[0])
        sizer.Add(self.image_size)
        sizer.Add(self.image, flag=wx.ALIGN_CENTER)
        self.SetSizer(sizer)


class ImagePanel(wx.Panel):
    IMAGE_SIZE = {'large': (48, 36), 'medium': (30, 22), 'small': (24, 16)}
    def __init__(self, parent, image_name, size, *args, **kwargs):
        super(ImagePanel, self).__init__(parent, *args, **kwargs)
        self.images = parent.images
        self.image_sizer = wx.BoxSizer(wx.HORIZONTAL)
        self.refresh(image_name, size)

    def refresh(self, image_name, size):
        self.clear_sizer(self.image_sizer)
        image_size = self.IMAGE_SIZE[size]
        image = self.images[image_name]
        #image = copy.deepcopy(self.images[image_name])

        image.Rescale(image_size[0], image_size[1], wx.IMAGE_QUALITY_HIGH)
        bitmap = wx.Bitmap(image)
        static_bitmap = wx.StaticBitmap(self, bitmap=bitmap)
        self.image_sizer.Add(static_bitmap)
        self.SetSizer(self.image_sizer)

    @staticmethod
    def clear_sizer(sizer):
        for child in sizer.GetChildren():
            sizer_child = child.GetWindow()
            sizer_child.Hide()
            sizer.Detach(sizer_child)


if __name__ == '__main__':
    """Run the application."""
    screen_app = wx.App()
    main_frame = MainFrame()
    screen_app.MainLoop()

1 Ответ

1 голос
/ 05 мая 2019

wx.Image имеет собственную функцию Copy, которая хорошо подойдет для ваших целей.

image = self.images[image_name]
#image = copy.deepcopy(self.images[image_name])
image = image.Copy()
...