import multiprocessing
from PIL import Image
name = input("Enter the file name: ")
def decode_file(filename):
with open(filename, mode='rb') as file:
binary_data = file.read()
binary_list = []
for byte in binary_data:
binary_list.append(format(byte, '08b'))
return binary_list
binary_list = decode_file(name)
l = len(binary_list)
no_of_bytes = l // 8
def make_row_list():
row_list = []
for i in range(0, l, 135):
row_list.append(binary_list[i:i + 135])
return row_list
row_list = make_row_list()
def fill_row(shared_pixels, width, row_data, count):
x_coordinate = 0
for byte in row_data:
for bit in byte:
index = x_coordinate + count * width
shared_pixels[index] = int(bit)
x_coordinate += 1
def fill_img(width, height):
shared_pixels = multiprocessing.Array('i', width * height)
processes = []
count = 0
for row_data in row_list:
p = multiprocessing.Process(target=fill_row, args=(shared_pixels, width, row_data, count))
p.start()
processes.append(p)
count += 1
for process in processes:
process.join()
return shared_pixels
def create_img():
width, height = 1080, 1920
image = Image.new('1', (width, height))
if no_of_bytes <= 135:
x_coordinate = 0
for byte in binary_list:
for bit in byte:
image.putpixel((x_coordinate, 0), int(bit))
x_coordinate += 1
elif no_of_bytes <= 259200:
shared_pixels = fill_img(width, height)
for y in range(height):
for x in range(width):
image.putpixel((x, y), shared_pixels[x + y * width])
image.save('hi.png')
image.show()
create_img()
When i run this program it asks for file name then keeps asking for file name indefinitely. The program was running fine before i added multiprocessing. So i think multiprocessing is to be blamed for this. I am new with multiprocessing so any help will be much appreciated :D
This happens because in Python when you create new processes using the multiprocessing
module, each new process starts by importing the main module, which includes executing the input
statement again.
To fix this, protect the code that should run once (like the input
statement and other statements) with an if __name__ == "__main__":
block. This way, the code won't run when imported by a new process:
Here is a working version:
import multiprocessing
from PIL import Image
def decode_file(filename):
with open(filename, mode='rb') as file:
binary_data = file.read()
binary_list = []
for byte in binary_data:
binary_list.append(format(byte, '08b'))
return binary_list
def make_row_list(binary_list): # added binary_list
row_list = []
l = len(binary_list)
for i in range(0, l, 135):
row_list.append(binary_list[i:i + 135])
return row_list
def fill_row(shared_pixels, width, row_data, count):
x_coordinate = 0
for byte in row_data:
for bit in byte:
index = x_coordinate + count * width
shared_pixels[index] = int(bit)
x_coordinate += 1
def fill_img(width, height, row_list): # added row_list
shared_pixels = multiprocessing.Array('i', width * height)
processes = []
count = 0
for row_data in row_list:
p = multiprocessing.Process(target=fill_row, args=(shared_pixels, width, row_data, count))
p.start()
processes.append(p)
count += 1
for process in processes:
process.join()
return shared_pixels
def create_img(binary_list, no_of_bytes): # added binary_list and no_of_bytes
width, height = 1080, 1920
image = Image.new('1', (width, height))
if no_of_bytes <= 135:
x_coordinate = 0
for byte in binary_list:
for bit in byte:
image.putpixel((x_coordinate, 0), int(bit))
x_coordinate += 1
elif no_of_bytes <= 259200:
# calling make_row_list here
row_list = make_row_list(binary_list)
shared_pixels = fill_img(width, height, row_list)
for y in range(height):
for x in range(width):
image.putpixel((x, y), shared_pixels[x + y * width])
image.save('hi.png')
image.show()
if __name__ == "__main__":
name = input("Enter the file name: ")
binary_list = decode_file(name)
no_of_bytes = len(binary_list) // 8
create_img(binary_list, no_of_bytes)