Ways of applying image effects on Python3 in the same window - atom-editor

So the thing is that I started with python not so long ago and I'm trying to get some code to work. Basically what I'm trying to to is create a window that contains an image and when some buttons are pressed, the image changes (size, blur, etc...) Some of the problems I'm encountering is the blur only taking effect once and the resize effect creating another image above the bigger/smaller one and the latter one not being deleted. is there a way to make all this to work? Thank you in advance.
I may have used too many lines of code, I'm fully aware of it as I still don't have enough knowledge :).
import tkinter
import cv2
import PIL.Image, PIL.ImageTk
def blur_image():
print("Blur")
global photo_blur
global cv_img_blur
cv_img_blur = cv2.blur(cv_img, (3, 3))
photo_blur = PIL.ImageTk.PhotoImage(image = PIL.Image.fromarray(cv_img_blur))
canvas.create_image(0, 0, image=photo_blur, anchor=tkinter.NW)
def reduce_image():
print("Reduced")
global photo_reduce
global cv_img_reduce
cv_img_reduce = cv2.resize(cv_img, (0,0), fx=0.5, fy=0.5, interpolation=cv2.INTER_AREA)
photo_reduce = PIL.ImageTk.PhotoImage(image = PIL.Image.fromarray(cv_img_reduce))
canvas.create_image(0, 0, image=photo_reduce, anchor=tkinter.NW)
window = tkinter.Tk()
window.title("Project")
cv_img = cv2.cvtColor(cv2.imread("hqdefault.jpg"), cv2.COLOR_BGR2RGB)
height, width, no_channels = cv_img.shape
canvas = tkinter.Canvas(window, width = width, height = height)
canvas.pack()
photo = PIL.ImageTk.PhotoImage(image = PIL.Image.fromarray(cv_img))
canvas.create_image(0, 0, image=photo, anchor=tkinter.NW)
btn_blur=tkinter.Button(window, text="Blur", width=50, command=blur_image)
btn_blur.pack(anchor=tkinter.CENTER, expand=True)
btn_reduce=tkinter.Button(window, text="Reduce", width=50, command=reduce_image)
btn_reduce.pack(anchor=tkinter.CENTER, expand=True)
window.mainloop()

Try something like this
import tkinter
import cv2
import PIL.Image, PIL.ImageTk
blur_status = (3, 3)
def blur_image():
print("Blur")
global photo_blur, cv_img_blur, image, blur_status
cv_img_blur = cv2.blur(cv_img, blur_status)
photo_blur = PIL.ImageTk.PhotoImage(image = PIL.Image.fromarray(cv_img_blur))
canvas.delete(image)
image = canvas.create_image(0, 0, image=photo_blur, anchor=tkinter.NW)
n1, n2 = blur_status
blur_status = (n1 + 1, n2 + 2)
def reduce_image():
print("Reduced")
global photo_reduce, cv_img_reduce, image
cv_img_reduce = cv2.resize(cv_img, (0,0), fx=0.5, fy=0.5, interpolation=cv2.INTER_AREA)
photo_reduce = PIL.ImageTk.PhotoImage(image = PIL.Image.fromarray(cv_img_reduce))
canvas.delete(image)
image = canvas.create_image(0, 0, image=photo_reduce, anchor=tkinter.NW)
window = tkinter.Tk()
window.title("Project")
cv_img = cv2.cvtColor(cv2.imread("home.png"), cv2.COLOR_BGR2RGB)
height, width, no_channels = cv_img.shape
canvas = tkinter.Canvas(window, width = width, height = height)
canvas.pack()
photo = PIL.ImageTk.PhotoImage(image = PIL.Image.fromarray(cv_img))
image = canvas.create_image(0, 0, image=photo, anchor=tkinter.NW)
btn_blur = tkinter.Button(window, text="Blur", width=50, command=blur_image)
btn_blur.pack(anchor=tkinter.CENTER, expand=True)
btn_reduce = tkinter.Button(window, text="Reduce", width=50, command=reduce_image)
btn_reduce.pack(anchor=tkinter.CENTER, expand=True)
window.mainloop()
In realtà le funzioni che hai chiamato sono andate a sovrapporre le immagini perché ne hanno sempre create di nuove senza modificare quelle precedentemente create, quindi prima di creare una nuova imagine bisogna eliminare quella vecchia. La sfocatura sembrava funzionare solo la prima volta perché i valori non aumentavano perché erano sempre impostati su (3, 3), se vuoi che "lavori più volte" devi aumentare i valori each time that you call the function

Related

Python Pygame TypeError: argument 1 must be pygame.Surface, not str

I dont know how to fix them bug. Please help me:(
I want the fish to be animated.
import pygame
import random
import os
pygame.init()
class Game:
def __init__(self):
super().__init__()
self.WIDTH, self.HEIGHT = 1100, 700
self.player = Player()
self.player_id = self.player.id
self.main()
def main(self):
FPS = 60
clock = pygame.time.Clock()
run = True
while run:
clock.tick(FPS)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
self.draw()
pygame.display.update()
pygame.quit()
def draw(self):
#background
self.canvas = pygame.display.set_mode((self.WIDTH, self.HEIGHT))
space_background = pygame.transform.scale(pygame.image.load(os.path.join("Sprites", "background.png")), (self.WIDTH, self.HEIGHT))
pygame.display.set_caption("Akvarium")
self.canvas.blit(space_background, (0, 0))
#player
self.canvas.blit(self.player.player_fish, (self.player_id.x, self.player_id.y))
pygame.display.update()
class Sprites:
def __init__(self, x, y, id_width, id_height):
self.x, self.y = x, y
self.id = pygame.Rect(x, y, id_width, id_height)
def load_sprites(self, file_path):
sprites = [i for i in os.listdir(file_path)]
return sprites
class Player(Sprites):
IDLE = "idle"
SWIM = "swim"
LEFT = "left"
RIGHT = "right"
#player_img = pygame.image.load(os.path.join("Sprites/Player/idle_left", "tile000.png"))
def __init__(self):
x, y = 100, 100
self.player_width, self.player_height = 85, 60
super().__init__(x, y, self.player_width, self.player_height)
self.player_sprites = self.load_all_sprites()
self.movement = self.IDLE
self.directions = self.LEFT
self.tik()
def load_all_sprites(self):
sprite_sheed = {self.IDLE: {self.LEFT: [], self.RIGHT: []},
self.SWIM: {self.LEFT: [], self.RIGHT: []}}
sprite_sheed[self.IDLE][self.LEFT] = self.load_sprites("Sprites/Player/idle_left")
sprite_sheed[self.IDLE][self.RIGHT] = self.load_sprites("Sprites/Player/idle_right")
sprite_sheed[self.SWIM][self.LEFT] = self.load_sprites("Sprites/Player/swim_left")
sprite_sheed[self.SWIM][self.RIGHT] = self.load_sprites("Sprites/Player/swim_right")
return sprite_sheed
def animation(self, idx):
idx += 1
max_idx = len(self.player_sprites[self.movement][self.directions])
idx = idx % max_idx
return idx
def tik(self):
sprite_idx = self.animation(0)
self.player_img = self.player_sprites[self.movement][self.directions][int(sprite_idx)]
self.player_fish = pygame.transform.scale(self.player_img, (self.player_width, self.player_height))
Game()
a mistake is:
self.player_fish = pygame.transform.scale(self.player_img, (self.player_width, self.player_height))
TypeError: argument 1 must be pygame.Surface, not str
Python is an interpreted, high-level and general-purpose programming language. Python's design philosophy emphasizes code readability with its notable use of significant whitespace. Its language constructs and object-oriented approach aim to help programmers write clear, logical code for small and large-scale projects.
#correct code must be
self.player_fish = pygame.transform.scale(self.canvas,(self.player_width,self.player_height))
Here self.canvas is the surface and the size is corrrect.....
Hope it helps

Python has stopped working while adding sizer in scrolled panel in wxpython

import wx
import wx.adv
from wx.lib.masked import NumCtrl
import wx.lib.scrolledpanel
import wx.lib.masked as masked
from wx.lib.masked import Field, BaseMaskedTextCtrl
class mainWindow(wx.Frame):
def __init__(self, camera):
#inheritence
wx.Frame.__init__(self, None, style= wx.SYSTEM_MENU | wx.CAPTION | wx.CLOSE_BOX | wx.CLIP_CHILDREN, size=(1370,720),pos=(0,0))
self.Title = "Registration"
self.SetSize(1370,720)
self.Maximize(True)
self.SetBackgroundColour('#f0f0f0')
menubar = wx.MenuBar()
#main ui
self.mainpanel = wx.Panel(self, size=(1370,720), pos=(0,0))
self.mainpanel.SetBackgroundColour('#f0f0f0')
mid_font = wx.Font(22, wx.DECORATIVE,wx.ITALIC,wx.BOLD)
#------------form panel-------------
self.scroll_panel = wx.lib.scrolledpanel.ScrolledPanel(self.mainpanel,size=(380,540), pos=(30,20),style=wx.NO_BORDER)
self.namepanel = wx.Panel(self.scroll_panel,size=(350,800), pos=(0,0),style=wx.DOUBLE_BORDER)
self.namepanel.SetForegroundColour('#1b262c')
self.Sizer = wx.BoxSizer( wx.VERTICAL )
self.scroll_panel.SetSizer(self.Sizer)
small_font = wx.Font(11, wx.DECORATIVE,wx.ITALIC,wx.BOLD)
fname = wx.StaticText(self.namepanel, -1, "First Name",pos=(30,70))
fname.SetFont(small_font)
self.fname = wx.TextCtrl(self.namepanel, pos=(155,70), size=(160, 25))
mname = wx.StaticText(self.namepanel, -1, "Middle Name",pos=(30,110))
mname.SetFont(small_font)
self.mname = wx.TextCtrl(self.namepanel, pos=(155,110), size=(160, 25))
lname = wx.StaticText(self.namepanel, -1, "Last Name",pos=(30,150))
lname.SetFont(small_font)
self.lname = wx.TextCtrl(self.namepanel, pos=(155,150), size=(160, 25))
button_font = wx.Font(12, wx.DECORATIVE,wx.NORMAL,wx.BOLD)
self.add = wx.Button(self.namepanel, -1, "Confirm", pos=(110,200),size=(130, 30),style=wx.DOUBLE_BORDER)
#self.add.Bind(wx.EVT_BUTTON, self.addinfo)
self.add.SetBackgroundColour('#FFFFFF')
self.add.SetForegroundColour('#1b262c')
self.add.SetFont(button_font)
self.Sizer.Add( self.namepanel, 0, wx.CENTER|wx.ALL, 5 )
self.scroll_panel.SetupScrolling(scrollToTop=False)
class all_module(wx.Frame):
def __init__(self):
#inheritence
wx.Frame.__init__(self, None, style= wx.SYSTEM_MENU | wx.CAPTION | wx.CLOSE_BOX | wx.CLIP_CHILDREN,pos=(0,0))
self.infopanel = wx.Panel(self,size=(1000,780), pos=(0, 0),style=wx.DOUBLE_BORDER)
self.registration = wx.Button(self.infopanel, -1, "Registration", pos=(0,0),size=(130, 30),style=wx.DOUBLE_BORDER)
self.registration.Bind(wx.EVT_BUTTON, self.register)
def register(self, event):
window = mainWindow(camera)
window.Show()
app = wx.App()
window = all_module()
window.Show()
app.MainLoop()
This is our code in which there is a simple registration scrolled panel and it is added in boxsizer. when i press close button i got this error that python has stopped working. but when i remove the sizer and i place all static text and textctrl out side the sizer, the program closes smoothly. But if i add in sizer i got the error i tried all the ways like self.Close() and self.Destroy() but nothing has worked. Any suggestion would be appreciated for us, Thanks in advance!!
Python has stopped working
.

IDL: Button Widget stops updating after one push

I'm pretty new to IDL and as a way to learn I have tried to create a number guessing game. I have a Widget with three buttons: One that tells the program the number you are thinking of is larger than the one the computer asks about, one if it's smaller and one if it's correct.
My problem is that once you have pushed i.e. the larger button, if you press it again it won't do anything. E.g. the program starts to guess 500, if I press larger it guesses 750. If I now press larger again, the program doesn't respond.
My code is like this:
PRO test1_event, ev
WIDGET_CONTROL, ev.top, GET_UVALUE = stash
minimum = 0
maximum = 1000
IF (ev.Id EQ largerbutton) THEN BEGIN
minimum = (minimum+maximum)/2
maximum = maximum
ENDIF
IF (ev.Id EQ smallerbutton) THEN BEGIN
maximum = (minimum+maximum)/2
minimum = minimum
ENDIF
IF (ev.Id EQ correctbutton) THEN BEGIN
help2 = string('I got it!') ;This prints to a text widget
ENDIF
END
PRO test1
wBase = WIDGET_BASE(X_SCROLL_SIZE = 512, Y_SCROLL_SIZE = 512)
;wDraw = WIDGET_WINDOW(wBase, X_SCROLL_SIZE = 512, Y_SCROLL_SIZE = 512)
Lower = WIDGET_BUTTON(wBase, VALUE = 'Smaller', XOFFSET = 60, YOFFSET = 250)
Higher = WIDGET_BUTTON(wBase, VALUE = 'Larger', XOFFSET = 225, YOFFSET = 250)
Correct = WIDGET_BUTTON(wBase, VALUE = 'Correct', XOFFSET = 380, YOFFSET = 250)
minimum = 0
maximum = 1000
help1 = string('Please think of a number between' + string(minimum) + ' and ' + string(maximum))
help2 = string('Is your number ' + string((minimum + maximum)/2) + '?')
wText = WIDGET_TEXT(wBase, VALUE = ['Welcome to my little game. I will now try and guess a number you are thinking of.'], XSIZE = 63,XOFFSET = 50, YOFFSET = 100)
wText1 = WIDGET_TEXT(wBase, VALUE = help1, XSIZE = 63,XOFFSET = 50, YOFFSET = 120)
wText2 = WIDGET_TEXT(wBase, VALUE = help2, XSIZE = 63,XOFFSET = 50, YOFFSET = 140)
stash = {text1:wText, text2:wText1, text3:wText2, $
lower:Lower, higher:Higher, correct:Correct, minimum:minimum, maximum:maximum}
WIDGET_CONTROL, wBase, SET_UVALUE = stash, /REALIZE
XMANAGER, 'test1', wBase
end
I have tried using a while loop and also REPEAT, but then the program just goes right up to 999 if I press the larger button and to 0 if I press the smaller.
Any ideas to what I can do?
EDIT: Added the rest of the program
I think the buttons are working fine but your event handler doesn't actually do anything. First, I needed to change largerbutton, smallerbutton, and correctbutton to be stash.higher, stash.lower, stash.correct. Then, your code calculates the new minimum & maximum but it doesn't actually do anything with them.
I put a print statement into the event code and it's definitely getting the button presses.
In your event handler you probably want to use widget_control to update the text box with the new guess.

Hidden OK button because of window size in Tcl-tk

I have the following problem, described in the image above.
Actually sometimes when I use my script the "OK" button shows, and not at other times when I use the script. If I make the window bigger myself, using my mouse it will then show up (It was previously hidden because the window was to small). I don't understand why and I couldn't find anything really helpful on the internet. (Changing stuff like the value of padx and pady didn't work.)
There has to be a parameter to adjust the general window size but I can't find it.
My second problem is that if the strings are long as in the example; a scroll bar to scroll from left to right will show. I would like to show the full strings. I also don't know how to fix that, sadly.
Is there something to do about it?
My code is the following:
noms_var_manif is a character vector
win2 <- tktoplevel()
tkgrid(tk2label(win2, text = "Veuillez selectionner les variables appartenant à ce bloc",
wraplength = 200, justify = "left"),
padx = 10, pady = c(15, 5), sticky = "w", columnspan = 2)
# Note that 'selection' uses indices starting at 1, like R and not Tcl/Tk!
win2$env$lst <- tk2listbox(win2,values=noms_var_manif, height = 10, selectmode = "extended")
tkgrid(win2$env$lst, padx = 100, pady = c(10, 20), sticky = "ew", columnspan = 2)
onOK <- function() {
select_var_bloc<- noms_var_manif[as.numeric(tkcurselection(win2$env$lst)) + 1]
tkdestroy(win2)
if (!length(select_var_bloc)) {
msg <- "Il n'y a donc aucune variable dans ce bloc?"
} else {
msg <- paste0("Vous avez choisi les variables suivantes: ",
paste(select_var_bloc, collapse = ", "))
}
tkmessageBox(message = msg)
win2$env$select_var_bloc= select_var_bloc
tkdestroy(win2)
}
win2$env$butOK <-tk2button(win2, text = "OK ", width = -6, command = onOK)
tkgrid(win2$env$butOK, padx = 10, pady = c(10, 15))
tkwait.window(win2)
select_var_bloc=win2$env$select_var_bloc
What you want to do is (1) fix the height and width of the the listbox, and
(2) fix the height and width of the window so that it is big enough to allow the OK button to always show. You can also fix the window so that it cannot be resized.

QScrollArea won't acknowledge set widget's size

I'm trying to implement a pinterest-like UI and I've been experimenting with the FlowLayout example for PySide.
The problem is that I'm trying to use a QScrollArea and it won't let me scroll down enough. In other words, I can't get to the bottom of the widget I'm trying to scroll.
You can get the hole file here. If you download it and run it, the problem will become pretty obvious.
My code was taken from here, with these modifications:
Added this class: (it just let's me generate colored and numerated rectangles)
class ColoredRectangle(QLabel):
count = 0
def __init__(self, height, color):
super(ColoredRectangle, self).__init__()
palette = QPalette()
palette.setColor(QPalette.Background, color)
self.setAutoFillBackground(True)
self.setPalette(palette)
self.setFixedSize(200, height)
self.setText(str(ColoredRectangle.count))
ColoredRectangle.count += 1
Now I'm adding rectangles instead of buttons...
class Window(QtGui.QWidget):
def __init__(self):
super(Window, self).__init__()
flowLayout = FlowLayout()
flowLayout.addWidget(ColoredRectangle(450, Qt.white))
flowLayout.addWidget(ColoredRectangle(200, Qt.green))self.setLayout(flowLayout)
self.setLayout(flowLayout)
self.setWindowTitle("Flow Layout")
Changed the doLayout method like this:
def doLayout(self, rect):
if not any(self.itemList):
return
firstItem = self.itemList[0]
x = rect.x()
y = rect.y()
wid = firstItem.widget()
spaceX = self.spacing() + wid.style().layoutSpacing(QtGui.QSizePolicy.PushButton,
QtGui.QSizePolicy.PushButton, QtCore.Qt.Horizontal)
spaceY = self.spacing() + wid.style().layoutSpacing(QtGui.QSizePolicy.PushButton,
QtGui.QSizePolicy.PushButton, QtCore.Qt.Vertical)
itemWidth = firstItem.sizeHint().width()
# calculate column count
columnCount = (rect.width() + spaceX) / (itemWidth + spaceX)
availablePositions = [None] * columnCount
for i in range(columnCount):
availablePositions[i] = QPoint(x + i * (itemWidth + spaceX), y)
for item in self.itemList:
currentPosition = availablePositions[0]
currentPositionColumn = 0
positionColumn = 0
for position in availablePositions:
if min(currentPosition.y(), position.y()) != currentPosition.y():
currentPositionColumn = positionColumn
currentPosition = position
positionColumn += 1
# update available position in column
itemSize = item.sizeHint()
availablePositions[currentPositionColumn] = QPoint(currentPosition.x(),
currentPosition.y() + itemSize.height() + spaceY)
# place item
item.setGeometry(QtCore.QRect(currentPosition, itemSize))
And finally, I added the QScrollArea:
if __name__ == '__main__':
import sys
app = QtGui.QApplication(sys.argv)
mainWin = Window()
scrollArea = QScrollArea()
scrollArea.setWidgetResizable(True)
scrollArea.setWidget(mainWin)
scrollArea.show()
sys.exit(app.exec_())
Thanks in advance!
Well, found the answer on my own...
Apparently the layout has to define the method heightForWidth, which, as far as I understand, returns the height of the layout which results after a width resize. So... I had to store the new height at the end of doLayout so I'm able to return it when asked for.
This is what I did after doLayout:
self.heightForWidthValue = max(map(lambda position : position.y(), availablePositions))
Also, I implemented these functions in FlowLayout:
def hasHeightForWidth(self):
return True
def heightForWidth(self, width):
return self.heightForWidthValue
And set 0 as the default value (initialized in FlowLayout->__init__) for heightForWidthValue.
Now it works like a charm :)
Here's the proper code, if anyone is interested.

Resources