So I am trying to create an image and then modifie it (by a shader), to do so i would like to use multiprocessing.
So the image is 1000 pixels wide, and for every 250 px i would calculate the lighting based on my function shader_pixel().
But I keep getting an error, I tried messing arround with the code but nothing worked.
Here is the error:
”’
Traceback (most recent call last):
File “d:NSICupidontest optimisation lights.py”, line 79, in
p1.start()
File “C:Program FilesWindowsAppsPythonSoftwareFoundation.Python.3.11_3.11.2544.0_x64__qbz5n2kfra8p0Libmultiprocessingprocess.py”, line 121, in start
self._popen = self._Popen(self)
^^^^^^^^^^^^^^^^^
File “C:Program FilesWindowsAppsPythonSoftwareFoundation.Python.3.11_3.11.2544.0_x64__qbz5n2kfra8p0Libmultiprocessingcontext.py”, line 224, in _Popen
return _default_context.get_context().Process._Popen(process_obj)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File “C:Program FilesWindowsAppsPythonSoftwareFoundation.Python.3.11_3.11.2544.0_x64__qbz5n2kfra8p0Libmultiprocessingcontext.py”, line 336, in _Popen
return Popen(process_obj)
^^^^^^^^^^^^^^^^^^
File “C:Program FilesWindowsAppsPythonSoftwareFoundation.Python.3.11_3.11.2544.0_x64__qbz5n2kfra8p0Libmultiprocessingpopen_spawn_win32.py”, line 95, in init
reduction.dump(process_obj, to_child)
File “C:Program FilesWindowsAppsPythonSoftwareFoundation.Python.3.11_3.11.2544.0_x64__qbz5n2kfra8p0Libmultiprocessingreduction.py”, line 60, in dump
ForkingPickler(file, protocol).dump(obj)
TypeError: cannot pickle ‘_tkinter.tkapp’ object
PS D:NSICupidon> Traceback (most recent call last):
File “”, line 1, in
File “C:Program FilesWindowsAppsPythonSoftwareFoundation.Python.3.11_3.11.2544.0_x64__qbz5n2kfra8p0Libmultiprocessingspawn.py”, line 108, in spawn_main
source_process = _winapi.OpenProcess(
^^^^^^^^^^^^^^^^^^^^
OSError: [WinError 87] This parameter is incorrect
”’
Here is the code:
‘
import tkinter as tk
from PIL import Image, ImageTk
import math, time
from multiprocessing import Process
def non_lerp(a: float, b: float, t: float) -> float:
“””Interpolation non linéaire entre a et b en fonction du temps t”””
return ((1 – t) * a)/1.5 + (t * b)/10
def shader_pixel(x_begin, x_end, lightposes, light_calculations):
for obj in range(len(light_calculations)):
for x in range(x_begin, x_end): # on parcourt les pixels en colonne
for y in range(hauteur): # on parcourt les pixels en ligne
r = light_calculations[obj][3].getpixel((x, y))[0]
v = light_calculations[obj][3].getpixel((x, y))[1]
b = light_calculations[obj][3].getpixel((x, y))[2]
g = int((light_calculations[obj][3].getpixel((x,y))[0]+light_calculations[obj][3].getpixel((x,y))[1]+light_calculations[obj][3].getpixel((x,y))[2])/3)
total_light_intensites = []
if not(r==0 and b == 0 and v ==0):
for i in range(len(lightposes)):
distance = math.sqrt((lightposes[i][0]-x)**2+(lightposes[i][1]-y)**2)
if distance <= lightposes[i][2]:
r+=lightposes[i][4][0]
v+=lightposes[i][4][1]
b+=lightposes[i][4][2]
base_intensite = lightposes[i][3]
pointlight_intensite = 0.0001
if((distance/lightposes[i][2])+(lightposes[i][3])<=1):
pointlight_intensite = non_lerp(1,0.1,(distance/lightposes[i][2])+(lightposes[i][3]))
total_light_intensites.append(pointlight_intensite)
red_color,green_color,blue_color = obj*5,obj*5,obj*5
for i in range(len(total_light_intensites)):
red_color += int(total_light_intensites[i]*(r*g)/200)
green_color += int(total_light_intensites[i]*(v*g)/200)
blue_color += int(total_light_intensites[i]*(b*g)/200)
final_pixel_color = (red_color,green_color,blue_color)
light_calculations[obj][2].putpixel((x,y),final_pixel_color)
if name == “main“:
light_calculations = []
lightposes=[] #1st = xpose, 2nd = ypose, 3rd = size, 4th = intensity (inversed), 5th = colour
startTime = time.time()
# ------------------------------ éléments de la fenêtre --------------------------------------
fenetre=tk.Tk() # on créé la fenêtre
largeur=1000 # on définit les dimensions de la fenêtre
hauteur=600
fenetre.geometry('1000x700')
fenetre.configure(background='#7ace54')
# ------------jeu------------------
toile = tk.Canvas(fenetre, width=largeur, height=hauteur) # on crée une "toile" dans la fen^tre dans laquelle on pourra dessiner
bouton = tk.Button(fenetre, text='Quitter', command = fenetre.destroy) # on crée un bouton pour quitter le jeu
toile.pack() # on place la toile dans la fenêtre
bouton.pack() # on place le bouton dans la fenêtre
fond1 = Image.open("img/fond.png") # on ouvre l'image à modifier
fond1 = fond1.resize((largeur, hauteur)) # on redimensionne l'image par rapport à la taille de la fenêtre
fond2 = fond1.copy() # on créé une copie de cette image
fond3 = ImageTk.PhotoImage(fond2, master = toile)
# on les ajoutes à la toile
main_image = toile.create_image(largeur/2,hauteur/2, image = fond3)
#--------------light calculations-----------------
light_calculations.append([main_image, fond3, fond2, fond1])
#illumination globale
lightposes.append([500, 300, 1000, 0.85, [2,20,10]])
lightposes.append([1400, -200, 2050, 0.42, [0,170,60]])
lightposes.append([200, -1200, 1900, 0.01, [0,12,40]])
#---------------------multiprocesssing---------------------------------
p1 = Process(target= shader_pixel, args=(0, 250, lightposes, light_calculations))
p2 = Process(target= shader_pixel, args=(250, 500, lightposes, light_calculations))
p3 = Process(target= shader_pixel, args=(500, 750, lightposes, light_calculations))
p4 = Process(target= shader_pixel, args=(750, 1000, lightposes, light_calculations))
p1.start()
p2.start()
p3.start()
p4.start()
for obj in range(len(light_calculations)):
light_calculations[obj][1] = ImageTk.PhotoImage(light_calculations[obj][2], master = toile)
toile.itemconfigure(light_calculations[obj][0], image = light_calculations[obj][1])
print(time.time()-startTime)
fenetre.mainloop() # permet à la fenêtre "d'écouter" les évènements en boucle
‘
If you have an idea on what’s causing this, please help me.
I tried to modifie the code and looked online for solutions but still didn’t work.
Isidore BILLARD is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.