Загрузка изображения, сгенерированного из массива, во фрейм wxpython - PullRequest
0 голосов
/ 12 июня 2019

Я пытаюсь создать программу для отображения изображений DICOM и перемещения по фрагментам с помощью кнопок событий.Сначала я хочу проверить это при перемещении по z-фрагментам массива np.array.Код основан на примере средства просмотра файлов в режиме онлайн.

Как я могу получить кнопку тестирования для вызова случайно сгенерированного изображения?

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

import os
import wx
import numpy as np
from PIL import Image

data = np.random.randint(low = 0, high = 255, size =(200, 200)) #generation of random array
test_img = Image.fromarray(data.astype('uint8')) #turn array into image

class PhotoCtrl(wx.App):
    def __init__(self, redirect=False, filename=None):
        wx.App.__init__(self, redirect, filename)
        self.frame = wx.Frame(None, title='Slice Viewer')
        self.panel = wx.Panel(self.frame) 
        self.PhotoMaxSize = 200 
        self.createWidgets()
        self.frame.Show()

    def createWidgets(self):
        instructions = 'Browse for an image'
        img = wx.EmptyImage(200,200)
        self.imageCtrl = wx.StaticBitmap(self.panel, wx.ID_ANY, 
                                         wx.BitmapFromImage(img))

        instructLbl = wx.StaticText(self.panel, label=instructions)
        self.photoTxt = wx.TextCtrl(self.panel, size=(100,-1))
        browseBtn = wx.Button(self.panel, label='Browse')
        browseBtn.Bind(wx.EVT_BUTTON, self.onBrowse)

        up_btn = wx.Button(self.panel, label='Up')
        up_btn.Bind(wx.EVT_BUTTON, self.on_press_up) 

        down_btn = wx.Button(self.panel, label='Down')
        down_btn.Bind(wx.EVT_BUTTON, self.on_press_down)

        test_btn = wx.Button(self.panel, label='Test')
        test_btn.Bind(wx.EVT_BUTTON, self.onViewTest)

        self.mainSizer = wx.BoxSizer(wx.VERTICAL)
        self.sizer = wx.BoxSizer(wx.HORIZONTAL)

        self.mainSizer.Add(wx.StaticLine(self.panel, wx.ID_ANY), 0, wx.ALL|wx.EXPAND, 5)
        self.mainSizer.Add(instructLbl, 0, wx.ALL, 5)
        self.mainSizer.Add(self.imageCtrl, 0, wx.ALL, 5)
        self.sizer.Add(self.photoTxt, 0, wx.ALL, 5)
        self.sizer.Add(browseBtn, 0, wx.ALL, 5)   
        self.mainSizer.Add(up_btn, 0, wx.ALL, 5)
        self.mainSizer.Add(down_btn, 0, wx.ALL, 5)
        self.mainSizer.Add(test_btn, 0, wx.ALL, 5)
        self.mainSizer.Add(self.sizer, 0, wx.ALL, 5)

        self.panel.SetSizer(self.mainSizer)
        self.mainSizer.Fit(self.frame)

        self.panel.Layout()

    def onBrowse(self, event):
        """ 
        Browse for file mode for later testing
        """
        wildcard = "JPEG files (*.jpg)|*.jpg"
        dialog = wx.FileDialog(None, "Choose a file",
                               wildcard=wildcard,
                               style=wx.FD_OPEN)
        if dialog.ShowModal() == wx.ID_OK:
            self.photoTxt.SetValue(dialog.GetPath())
        dialog.Destroy() 
        self.onView()

    def onView(self):
        """
        Part of later data selection
        """
        filepath = self.photoTxt.GetValue()
        img = wx.Image(filepath, wx.BITMAP_TYPE_ANY)
        # scale the image, preserving the aspect ratio
        W = img.GetWidth()
        H = img.GetHeight()
        if W > H:
            NewW = self.PhotoMaxSize
            NewH = self.PhotoMaxSize * H / W
        else:
            NewH = self.PhotoMaxSize
            NewW = self.PhotoMaxSize * W / H
        img = img.Scale(NewW,NewH)

        self.imageCtrl.SetBitmap(wx.BitmapFromImage(img))
        self.panel.Refresh()

    def onViewTest(self):
        """
        Problem code area, trying to call the generated image and display
        """
        img = wx.Image(test_img, wx.BITMAP_TYPE_ANY)
        self.imageCtrl.SetBitmap(wx.BitmapFromImage(img))
        self.panel.Refresh()

    def on_press_up(self, event):
        print('up')

    def on_press_down(self, event):
        print('down')


if __name__ == '__main__':
    app = PhotoCtrl()
    app.MainLoop()

del app
'''

Currently i get a positional argument error, but don't understand why as the browse function works with only one argument.

Ответы [ 2 ]

1 голос
/ 12 июня 2019

Это ваш код исправлен для wxpython 4.0.4 с python 3
Вы заметите:

Изменение способа генерации тестового изображения
Изменение оператора if при выборе файла изображения
def из onViewTest

Надеюсь, эти изменения дадут вам то, что вы хотите.
Если вы по-прежнему используете wxPython 2.8, возможно, вам придется сохранить некоторые из существующих манипуляций с изображениями, поскольку wxPython 4+ изменил некоторые из них.

import os
import wx
import numpy as np
from PIL import Image

data = np.random.randint(low = 0, high = 255, size =(200, 200)) #generation of random array
#test_img = Image.fromarray(data.astype('uint8')) #turn array into image

class PhotoCtrl(wx.App):
    def __init__(self, redirect=False, filename=None):
        wx.App.__init__(self, redirect, filename)
        self.frame = wx.Frame(None, title='Slice Viewer')
        self.panel = wx.Panel(self.frame)
        self.PhotoMaxSize = 200
        self.createWidgets()
        self.frame.Show()

    def createWidgets(self):
        instructions = 'Browse for an image'
        img = wx.Image(200,200)
        self.imageCtrl = wx.StaticBitmap(self.panel, wx.ID_ANY,
                                         wx.Bitmap(img))

        instructLbl = wx.StaticText(self.panel, label=instructions)
        self.photoTxt = wx.TextCtrl(self.panel, size=(100,-1))
        browseBtn = wx.Button(self.panel, label='Browse')
        browseBtn.Bind(wx.EVT_BUTTON, self.onBrowse)

        up_btn = wx.Button(self.panel, label='Up')
        up_btn.Bind(wx.EVT_BUTTON, self.on_press_up)

        down_btn = wx.Button(self.panel, label='Down')
        down_btn.Bind(wx.EVT_BUTTON, self.on_press_down)

        test_btn = wx.Button(self.panel, label='Test')
        test_btn.Bind(wx.EVT_BUTTON, self.onViewTest)

        self.mainSizer = wx.BoxSizer(wx.VERTICAL)
        self.sizer = wx.BoxSizer(wx.HORIZONTAL)

        self.mainSizer.Add(wx.StaticLine(self.panel, wx.ID_ANY), 0, wx.ALL|wx.EXPAND, 5)
        self.mainSizer.Add(instructLbl, 0, wx.ALL, 5)
        self.mainSizer.Add(self.imageCtrl, 0, wx.ALL, 5)
        self.sizer.Add(self.photoTxt, 0, wx.ALL, 5)
        self.sizer.Add(browseBtn, 0, wx.ALL, 5)
        self.mainSizer.Add(up_btn, 0, wx.ALL, 5)
        self.mainSizer.Add(down_btn, 0, wx.ALL, 5)
        self.mainSizer.Add(test_btn, 0, wx.ALL, 5)
        self.mainSizer.Add(self.sizer, 0, wx.ALL, 5)

        self.panel.SetSizer(self.mainSizer)
        self.mainSizer.Fit(self.frame)

        self.panel.Layout()

    def onBrowse(self, event):
        """
        Browse for file mode for later testing
        """
        wildcard = "JPEG files (*.jpg)|*.jpg"
        dialog = wx.FileDialog(None, "Choose a file",
                               wildcard=wildcard,
                               style=wx.FD_OPEN)
        if dialog.ShowModal() == wx.ID_OK:
            self.photoTxt.SetValue(dialog.GetPath())
            dialog.Destroy()
            self.onView()

    def onView(self):
        """
        Part of later data selection
        """
        filepath = self.photoTxt.GetValue()
        img = wx.Image(filepath, wx.BITMAP_TYPE_ANY)
        # scale the image, preserving the aspect ratio
        W = img.GetWidth()
        H = img.GetHeight()
        if W > H:
            NewW = self.PhotoMaxSize
            NewH = self.PhotoMaxSize * H / W
        else:
            NewH = self.PhotoMaxSize
            NewW = self.PhotoMaxSize * W / H
        img = img.Scale(NewW,NewH)

        self.imageCtrl.SetBitmap(wx.Bitmap(img))
        self.panel.Refresh()

    def onViewTest(self, event):
        """
        Problem code area, trying to call the generated image and display
        """
#        img = wx.Image(test_img, wx.BITMAP_TYPE_ANY)
#        self.imageCtrl.SetBitmap(wx.BitmapFromImage(img))
        img = wx.Image(200,200)
        img.SetData(data)
        self.imageCtrl.SetBitmap(wx.Bitmap(img))
        self.panel.Refresh()

    def on_press_up(self, event):
        print('up')

    def on_press_down(self, event):
        print('down')


if __name__ == '__main__':
    app = PhotoCtrl()
    app.MainLoop()

del app

Your random test image

Отображается ваше «случайное» тестовое изображение

0 голосов
/ 12 июня 2019

Вы получаете ошибку позиционного аргумента, поскольку для метода def onViewTest (self): требуется второй аргумент, например def onViewTest (self, event):

Вторая ошибка: переменная test_img требует строку для пути к файлу изображения. Вы можете сделать что-то вроде следующего:

def onView(self):
    """
    Part of later data selection
    """
    filepath = self.photoTxt.GetValue()
    self.filepath = filepath

, а затем

def onViewTest(self, event):
    """
    Fixed code area, to call the generated image and display
    """
    img = wx.Image(self.filepath, wx.BITMAP_TYPE_ANY)

Теперь все исправлено.

...