I'm working with the base64 module for image manipulation.
I've got this code:
import flask, base64, webbrowser, PIL.Image
...
...
image = PIL.Image.frombytes(mode='RGBA', size=(cam_width, cam_height), data=file_to_upload)
im_base64 = base64.b64encode(image.tobytes())
html = '<html><head><meta http-equiv="refresh" content="0.5"><title>Displaying Uploaded Image</title></head><body><h1>Displaying Uploaded Image</h1><img src="data:;base64,{}" alt="" /></body></html>'.format(im_base64.decode('utf8'))
html_url = '/home/mark/Desktop/FlaskUpload/test.html'
with open(html_url, 'w') as f:
f.write(html)
webbrowser.open(html_url)
I've also tried:
html = '<html><head><meta http-equiv="refresh" content="0.5"><title>Displaying Uploaded Image</title></head><body><h1>Displaying Uploaded Image</h1><img src="data:;base64,"'+im_base64.decode('utf8')+'" alt="" /></body></html>'
The heading is being rendered just fine but not the image.
Have I missed anything ?
Update:
cam_width is 720
cam_height is 1280
file_to_upload is 3686400
first 10 bytes of the file_to_upload:
b'YPO\xffYPO\xffVQ'
I can't seem to get first 10 bytes of im_base64 with print(image.tobytes()[:10]) as it throws an error.
I got little bit closer to determining what's wrong. Once I fixed
the quotes I got error:
Traceback (most recent call last):
File "/home/mark/venv/lib/python3.7/site-packages/flask/app.py", line 2464, in __call__
return self.wsgi_app(environ, start_response)
File "/home/mark/venv/lib/python3.7/site-packages/flask/app.py", line 2450, in wsgi_app
response = self.handle_exception(e)
File "/home/mark/venv/lib/python3.7/site-packages/flask/app.py", line 1867, in handle_exception
reraise(exc_type, exc_value, tb)
File "/home/mark/venv/lib/python3.7/site-packages/flask/_compat.py", line 39, in reraise
raise value
File "/home/mark/venv/lib/python3.7/site-packages/flask/app.py", line 2447, in wsgi_app
response = self.full_dispatch_request()
File "/home/mark/venv/lib/python3.7/site-packages/flask/app.py", line 1952, in full_dispatch_request
rv = self.handle_user_exception(e)
File "/home/mark/venv/lib/python3.7/site-packages/flask/app.py", line 1821, in handle_user_exception
reraise(exc_type, exc_value, tb)
File "/home/mark/venv/lib/python3.7/site-packages/flask/_compat.py", line 39, in reraise
raise value
File "/home/mark/venv/lib/python3.7/site-packages/flask/app.py", line 1950, in full_dispatch_request
rv = self.dispatch_request()
File "/home/mark/venv/lib/python3.7/site-packages/flask/app.py", line 1936, in dispatch_request
return self.view_functions[rule.endpoint](**req.view_args)
File "/home/mark/venv/server.py", line 28, in upload_file
image = PIL.Image.frombytes(mode='RGBA', size=(cam_width, cam_height), data=file_to_upload)
File "/home/mark/venv/lib/python3.7/site-packages/PIL/Image.py", line 2650, in frombytes
im.frombytes(data, decoder_name, args)
File "/home/mark/venv/lib/python3.7/site-packages/PIL/Image.py", line 797, in frombytes
d.setimage(self.im)
ValueError: tile cannot extend outside image
I'm working with image manipulation for the very first time so I don't know what I'm doing. What ValueError: tile cannot extend outside image means ?
To see where you are going wrong, you need to differentiate between:
RGB "pixel data", and
JPEG/PNG encoded images.
"Pixel data" is a bunch of RGB/RGBA bytes and that is all. There is no height or width information to know how to interpret or lay out the pixels on a screen. The data is just 4 RGBA bytes for each pixel. If you know your image is 720x1280 RGBA pixels, you will have 720x1280x4, or 3686400 bytes. Notice there's no room in there for height and width or the fact it's RGBA. That's what you have in your variable file_to_upload. Note that you had to additionally tell PIL Image the height and width and the fact it is RGBA for PIL to understand the pixel data.
A JPEG/PNG encoded image is very different. Firstly, it starts with a magic number, which is ff d8 for JPEG, and the 3 letters PNG and some other bits and pieces for PNG. Then it has the height and width, the bytes/pixel and colourspace and possibly the date and GPS location you took the photo, your copyright, the camera manufacturer and lens and a bunch of other stuff. Then it has the compressed pixel data. In general, it will be smaller than the corresponding pixel data. A JPEG/PNG is self-contained - no additional data is needed.
Ok, you need to send a base64-encoded JPEG or a PNG to the browser. Why? Because the browser needs an image with dimensions in it, else it can't tell if it is 720 px wide and 1280 px tall, or a single straight line of 921,600 RGBA pixels, or a single straight line of 1,228,800 RGB pixels. Your image is RGBA, so you probably better send a PNG because JPEGs cannot contain transparency.
So, where did you go wrong? You started with "pixel data", added in your knowledge of height and width and made a PIL Image. So far so good. But then you went wrong because you called tobytes() and made it back into exactly what you started with - "pixel data" with the same length and content as you had, and no width or height info. You should have instead, created an in-memory PNG-encoded image with the height and width embedded in it so that the browser knows its shape. Then base64-encode and send that. So you needed something like:
image = PIL.Image.frombytes(mode='RGBA', size=(cam_width, cam_height), data=file_to_upload)
buffer = io.BytesIO()
image.save(buffer, format="PNG")
PNG = buffer.getvalue()
Also, have a read here about checking the first few bytes of your data so you can readily check if you are sending the right thing.
So, here's the complete code:
#!/usr/bin/env python3
import base64
import numpy as np
from PIL import Image
from io import BytesIO
cam_width, cam_height = 640, 480
# Simulate some semi-transparent red pixel data
PixelData = np.full((cam_height,cam_width,4), [255,0,0,128], np.uint8)
# Convert to PIL Image
im = Image.frombytes(mode='RGBA', size=(cam_width, cam_height), data=PixelData)
# Create in-memory PNG
buffer = BytesIO()
im.save(buffer, format="PNG")
PNG = buffer.getvalue()
# Base64 encode
b64PNG = base64.b64encode(PNG).decode("utf-8")
# Create HTML
html = f'<html><head><meta http-equiv="refresh" content="0.5"><title>Displaying Uploaded Image</title></head><body><h1>Displaying Uploaded Image</h1><img src="data:;base64,{b64PNG}" alt="" /></body></html>'
# Write HTML
with open('test.html', 'w') as f:
f.write(html)
And the resulting, semi-transparent red image:
Related
I am trying to create a pptx or powerpoint file using python-pptx and reading the image using python wand library but getting error like AttributeError: 'Image' object has no attribute 'seek'. Did you mean: 'seed'?
Note: All the files are in same folder starts with 'watermarked_'
from io import FileIO
import os
from wand.image import Image
from pptx.util import Inches
from pptx import Presentation
def create_slide()->FileIO:
# Creating presentation object
root = Presentation()
for file in os.listdir():
if file.startswith('watermarked_'):
# Creating slide layout
first_slide_layout = root.slide_layouts[1]
slide = root.slides.add_slide(first_slide_layout)
shapes = slide.shapes
#Adding title or heading to the slide
title_shape = shapes.title
title_shape.text = f" Created By python-pptx for Watermarking "
#Adding sub-title with border to the slide
body_shape = shapes.placeholders[1]
tf = body_shape.text_frame
tf.text = f"This is a watermarked image of {file}"
with Image(filename = file) as watermarked_image:
#Maintianing the aspect ratio of the image
width, height = watermarked_image.size
ratio = height/width
new_width = width / 2
new_height = int(new_width * ratio)
watermarked_image.resize(int(new_width), new_height)
# Add the watermarked image to the slide
slide.shapes.add_picture(watermarked_image ,Inches(1), Inches(3))
root.save("Output.pptx")
create_slide()
Traceback (most recent call last):
File "/Users/quantum/Desktop/image/project.py", line 60, in <module>
quantum#MacBook-Air image % python -u "/Users/quantum/Desktop/image/project.py"
Traceback (most recent call last):
File "/Users/quantum/Desktop/image/project.py", line 60, in <module>
create_slide()
File "/Users/quantum/Desktop/image/project.py", line 57, in create_slide
slide.shapes.add_picture(watermarked_image ,Inches(1), Inches(3))
File "/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/site-packages/pptx/shapes/shapetree.py", line 332, in add_picture
image_part, rId = self.part.get_or_add_image_part(image_file)
File "/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/site-packages/pptx/parts/slide.py", line 39, in get_or_add_image_part
image_part = self._package.get_or_add_image_part(image_file)
File "/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/site-packages/pptx/package.py", line 36, in get_or_add_image_part
return self._image_parts.get_or_add_image_part(image_file)
File "/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/site-packages/pptx/package.py", line 151, in get_or_add_image_part
image = Image.from_file(image_file)
File "/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/site-packages/pptx/parts/image.py", line 168, in from_file
if callable(getattr(image_file, "seek")):
AttributeError: 'Image' object has no attribute 'seek'. Did you mean: 'seed'?
Any frequent help will be much appreciated
A wand.image.Image object is not a valid argument for Shapes.add_picture(). The first argument to that call needs to be the str path to an image file or a file-like object containing an image.
I suppose that means you'll need to save the modified image as a JPG or PNG or whatever and then provide the filename. You could also save it to a BytesIO object and pass that to .add_picture() as that would count as a file-like object and not require using the filesystem.
I've been developing my Dash web application and am now looking into hosting it on my VM.
After I set up my environment, I'm unable to directly load PIL Image objects in html.Img elements.
As they are rendered, an error will pop up and notify me that my PIL Image is not serializable.
This strikes me as weird, and possibly not an plotly error, but I have the exact same code, libraries and images causing error on my VM but running smoothly on my workstation.
After loading and doing some preprocessing, my Image object is passed to the html component as shown:
grid_main_images = <PIL.Image.Image image mode=RGB size=482x542 at 0x7FE88C04CD90>
html.Img(src=grid_main_imgs)
Again, the serialization error only occurs on my VM but not on my local machine.
And here is the full error / traceback
Traceback (most recent call last):
File "/home/aegilsson/anaconda3/envs/diamond/lib/python3.7/site-packages/dash/dash.py", line 1227, in add_context
cls=plotly.utils.PlotlyJSONEncoder
File "/home/aegilsson/anaconda3/envs/diamond/lib/python3.7/json/__init__.py", line 238, in dumps
**kw).encode(obj)
File "/home/aegilsson/anaconda3/envs/diamond/lib/python3.7/site-packages/_plotly_utils/utils.py", line 49, in encode
encoded_o = super(PlotlyJSONEncoder, self).encode(o)
File "/home/aegilsson/anaconda3/envs/diamond/lib/python3.7/json/encoder.py", line 199, in encode
chunks = self.iterencode(o, _one_shot=True)
File "/home/aegilsson/anaconda3/envs/diamond/lib/python3.7/json/encoder.py", line 257, in iterencode
return _iterencode(o, 0)
File "/home/aegilsson/anaconda3/envs/diamond/lib/python3.7/site-packages/_plotly_utils/utils.py", line 119, in default
return _json.JSONEncoder.default(self, obj)
File "/home/aegilsson/anaconda3/envs/diamond/lib/python3.7/json/encoder.py", line 179, in default
raise TypeError(f'Object of type {o.__class__.__name__} '
TypeError: Object of type Image is not JSON serializable
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/home/aegilsson/anaconda3/envs/diamond/lib/python3.7/site-packages/flask/app.py", line 2463, in __call__
return self.wsgi_app(environ, start_response)
File "/home/aegilsson/anaconda3/envs/diamond/lib/python3.7/site-packages/flask/app.py", line 2449, in wsgi_app
response = self.handle_exception(e)
File "/home/aegilsson/anaconda3/envs/diamond/lib/python3.7/site-packages/flask/app.py", line 1866, in handle_exception
reraise(exc_type, exc_value, tb)
File "/home/aegilsson/anaconda3/envs/diamond/lib/python3.7/site-packages/flask/_compat.py", line 39, in reraise
raise value
File "/home/aegilsson/anaconda3/envs/diamond/lib/python3.7/site-packages/flask/app.py", line 2446, in wsgi_app
response = self.full_dispatch_request()
File "/home/aegilsson/anaconda3/envs/diamond/lib/python3.7/site-packages/flask/app.py", line 1951, in full_dispatch_request
rv = self.handle_user_exception(e)
File "/home/aegilsson/anaconda3/envs/diamond/lib/python3.7/site-packages/flask/app.py", line 1820, in handle_user_exception
reraise(exc_type, exc_value, tb)
File "/home/aegilsson/anaconda3/envs/diamond/lib/python3.7/site-packages/flask/_compat.py", line 39, in reraise
raise value
File "/home/aegilsson/anaconda3/envs/diamond/lib/python3.7/site-packages/flask/app.py", line 1949, in full_dispatch_request
rv = self.dispatch_request()
File "/home/aegilsson/anaconda3/envs/diamond/lib/python3.7/site-packages/flask/app.py", line 1935, in dispatch_request
return self.view_functions[rule.endpoint](**req.view_args)
File "/home/aegilsson/anaconda3/envs/diamond/lib/python3.7/site-packages/dash/dash.py", line 1291, in dispatch
response.set_data(self.callback_map[output]['callback'](*args))
File "/home/aegilsson/anaconda3/envs/diamond/lib/python3.7/site-packages/dash/dash.py", line 1242, in add_context
).replace(' ', ''))
dash.exceptions.InvalidCallbackReturnValue:
The callback for property `children`
of component `tabs-content` returned a value
which is not JSON serializable.
In general, Dash properties can only be
dash components, strings, dictionaries, numbers, None,
or lists of those.
You need to base64 encode the image and add some HTML headers.
def pil_to_b64(im, enc_format="png", **kwargs):
"""
Converts a PIL Image into base64 string for HTML displaying
:param im: PIL Image object
:param enc_format: The image format for displaying. If saved the image will have that extension.
:return: base64 encoding
"""
buff = BytesIO()
im.save(buff, format=enc_format, **kwargs)
encoded = base64.b64encode(buff.getvalue()).decode("utf-8")
return encoded
html.Img(id="my-img",className="image", src="data:image/png;base64, " + pil_to_b64(pil_img))
Credit: #Atli's comment pointed me in the right direction.
Not sure when it was introduced but both plotly.express.imshow() and plotly.graph_objects.Figure().add_layout_image() do accept PIL image out of the box:
In fact, if you provide any incompatible input like np.array to fig.add_layout_image({"source":np.array(my_pil_img)}) you will get the following ValueError:
The 'source' property is an image URI that may be specified as:
A remote image URI string (e.g. 'http://www.somewhere.com/image.png')
A data URI image string (e.g. 'data:image/png;base64,iVBORw0KGgoAAAANSU')
A PIL.Image.Image object which will be immediately converted to a data URI image string See http://pillow.readthedocs.io/en/latest/reference/Image.html
Example:
from PIL import Image
#import pathlib
mysize = (512,512)
# if you have a real img
#path_to_file = pathlib.Path().cwd()/'dummy.png'
#img = Image.open(path_to_file)
# use dummy img here for example:
img = Image.new('RGBA', size=(1024, 1024), color=(155, 0, 0))
# I encountered issues with very big images, so best to make an in-place thumbnail
img = img.thumbnail(mysize, Image.ANTIALIAS)
Now for plotly.express:
import plotly.express as px
px.imshow(img)
or a bit more elaborate for plotly.graph_objects:
from plotly import graph_objects as go
fig = go.Figure()
# based on https://plotly.com/python/images/#zoom-on-static-images
# Constants
img_width, img_height = img.size
scale_factor = 1
# Add invisible scatter trace.
# This trace is added to help the autoresize logic work.
fig.add_trace(
go.Scatter(
x=[0, img_width * scale_factor],
y=[0, img_height * scale_factor],
mode="markers",
marker_opacity=0
)
)
# Configure axes
fig.update_xaxes(
visible=False,
range=[0, img_width * scale_factor]
)
fig.update_yaxes(
visible=False,
range=[0, img_height * scale_factor],
# the scaleanchor attribute ensures that the aspect ratio stays constant
scaleanchor="x"
)
# Add image
fig.add_layout_image(
dict(
x=0,
sizex=img_width * scale_factor,
y=img_height * scale_factor,
sizey=img_height * scale_factor,
xref="x",
yref="y",
opacity=1.0,
layer="below",
sizing="stretch",
source=img)
)
# Configure other layout
fig.update_layout(
width=img_width * scale_factor,
height=img_height * scale_factor,
margin={"l": 0, "r": 0, "t": 0, "b": 0},
)
# Disable the autosize on double click because it adds unwanted margins around the image
# More detail: https://plotly.com/python/configuration-options/
fig.show(config={'doubleClick': 'reset'})
I'm working on GCP cloud functions and intend to write a functions which combines two images. But I', getting the following error when I invoke the function:
Traceback (most recent call last): File
"/env/local/lib/python3.7/site-packages/google/cloud/functions/worker.py",
line 346, in run_http_function result =
_function_handler.invoke_user_function(flask.request) File "/env/local/lib/python3.7/site-packages/google/cloud/functions/worker.py",
line 217, in invoke_user_function return
call_user_function(request_or_event) File
"/env/local/lib/python3.7/site-packages/google/cloud/functions/worker.py",
line 210, in call_user_function return
self._user_function(request_or_event) File "/user_code/main.py", line
74, in execute newIntro= generateIntroImage(nameMappings['stdName'],
nameMappings['stdPicture'], nameMappings['logo'],
nameMappings['stdYear'], nameMappings['font']) File
"/user_code/main.py", line 12, in generateIntroImage
images.append(Image.open(logo)) File
"/env/local/lib/python3.7/site-packages/PIL/Image.py", line 2862, in
open "cannot identify image file %r" % (filename if filename else fp)
PIL.UnidentifiedImageError: cannot identify image file '/tmp/logo.jpg'
I have ran this function on my local machine and it works as expected but when I deploy it on GCP, it gives this error and crashes. Here's my function:
from PIL import Image
from PIL import ImageFont
from PIL import ImageDraw
def generateIntroImage(stdName, stdPicture, logo, year, typeFace):
images = [Image.open(x) for x in [stdPicture, logo]]
widths, heights = zip(*(i.size for i in images))
total_width = sum(widths)
max_height = max(heights)
new_im = Image.new('RGB', (total_width, max_height))
x_offset = 0
for im in images:
new_im.paste(im, (x_offset,0))
x_offset += im.size[0]
font= ImageFont.truetype(typeFace, 70)
draw= ImageDraw.Draw(new_im)
draw.text((0, 0), stdName+"'s " +year+" Year Book", (0,0,0),font= font)
fileName= "/tmp/test.jpg"
new_im.save(fileName)
return fileName
These images are .jpg and .png files. Any idea what could be wrong?
Happened to me on Google Colab as well, apparently updating PIL version fixed the problem for me.
PIL throws error because it cannot identify the image format. Most probably the reason is that the image is corrupted and hence cannot be read (or "identified") by pillow's Image.open(). For example if you try opening the image in an IPython prompt, it would fail as well.
In [2]: from PIL import Image
In [3]: Image.open("176678612.jpg")
---------------------------------------------------------------------------
UnidentifiedImageError Traceback (most recent call last)
<ipython-input-3-3f91b2f4e49a> in <module>
----> 1 Image.open("176678612.jpg")
/opt/conda/envs/swin/lib/python3.7/site-packages/PIL/Image.py in open(fp, mode, formats)
3022 warnings.warn(message)
3023 raise UnidentifiedImageError(
-> 3024 "cannot identify image file %r" % (filename if filename else fp)
3025 )
3026
UnidentifiedImageError: cannot identify image file '176678612.jpg'
And the relevant piece of code handling this check is from PIL.Image.open()
"""
exception PIL.UnidentifiedImageError: If the image cannot be opened and
identified.
"""
raise UnidentifiedImageError(
"cannot identify image file %r" % (filename if filename else fp)
So, the fix is to delete the image, or replace it with an uncorrupted version.
you need to provide a downloadable link to the image. What worked for me was click on the download image and the copy that URL.
I am making a simple OpenGL 3.3 OBJ viewer in Python using the modules Pyglet and Ratcave. I want to load a textured sphere I made in Blender. While my Pyglet/Ratcave OBJ viewer loads untextured OBJ files, when I add textures to my project, I get this error and the program fails to load:
ValueError: could not convert string to float: 'textures'
What does this mean?
I got a different error when I tried to import textures from my OneDrive folder and use them in my Blender project. When I put the textures in the same folder as the script and OBJ/MTL files, it got rid of that error, but now I can't load the textures because, for whatever reason, Ratcave needs to convert the textures to a float and it can't do that.
import pyglet
import ratcave as rc
import time
window = pyglet.window.Window()
def update(dt):
pass
pyglet.clock.schedule(update)
# Insert filename into WavefrontReader
obj_filename = 'Textured Sphere Eevee.obj'
obj_reader = rc.WavefrontReader(obj_filename)
# Check which meshes can be found inside the Wavefront file, and extract it into a Mesh object for rendering
print(obj_reader.bodies.keys())
Sphere = obj_reader.get_mesh("Cube")
Sphere.position.xyz = 0, 0, -10
scene= rc.Scene(meshes=[Sphere])
#window.event
def on_draw():
with rc.default_shader:
scene.draw()
#scene.clear()
#time.sleep(10)
pyglet.app.run()
Traceback (most recent call last):
File "C:\Users\Jeffery\Desktop\Art\Pyglet Game Engine\scripts\Ratcave_OBJ_Loader_Test 2.py", line 15, in <module>
obj_reader = rc.WavefrontReader(obj_filename)
File "C:\Users\Jeffery\AppData\Local\Programs\Python\Python37-32\lib\site-packages\ratcave\wavefront.py", line 28, in __init__
self.bodies = read_wavefront(file_name)
File "C:\Users\Jeffery\AppData\Local\Programs\Python\Python37-32\lib\site-packages\wavefront_reader\reading.py", line 114, in read_wavefront
materials = read_mtlfile(path.join(path.dirname(fname_obj), fname_mtl))
File "C:\Users\Jeffery\AppData\Local\Programs\Python\Python37-32\lib\site-packages\wavefront_reader\reading.py", line 88, in read_mtlfile
material[prefix] = tuple(float(d) for d in split_data)
File "C:\Users\Jeffery\AppData\Local\Programs\Python\Python37-32\lib\site-packages\wavefront_reader\reading.py", line 88, in <genexpr>
material[prefix] = tuple(float(d) for d in split_data)
ValueError: could not convert string to float: 'textures'
So i am trying to make a script that will auto upload images to facebook for me using RoboBrowser to navigate the mbasic.facebook.com website and i am getting a strange error when submitting the image form:
Traceback (most recent call last):
File "C:\Users\Admin\OneDrive\Facebook Project\facebook.py", line 55, in <module>
browser.submit_form(form, submit=form["add_photo_done"])
File "C:\Users\Admin\AppData\Local\Programs\Python\Python37-32\lib\site-packages\robobrowser\browser.py", line 343, in submit_form
response = self.session.request(method, url, **send_args)
File "C:\Users\Admin\AppData\Local\Programs\Python\Python37-32\lib\site-packages\requests\sessions.py", line 498, in request
prep = self.prepare_request(req)
File "C:\Users\Admin\AppData\Local\Programs\Python\Python37-32\lib\site-packages\requests\sessions.py", line 441, in prepare_request
hooks=merge_hooks(request.hooks, self.hooks),
File "C:\Users\Admin\AppData\Local\Programs\Python\Python37-32\lib\site-packages\requests\models.py", line 312, in prepare
self.prepare_body(data, files, json)
File "C:\Users\Admin\AppData\Local\Programs\Python\Python37-32\lib\site-packages\requests\models.py", line 500, in prepare_body
(body, content_type) = self._encode_files(files, data)
File "C:\Users\Admin\AppData\Local\Programs\Python\Python37-32\lib\site-packages\requests\models.py", line 159, in _encode_files
fdata = fp.read()
File "C:\Users\Admin\AppData\Local\Programs\Python\Python37-32\lib\encodings\cp1252.py", line 23, in decode
return codecs.charmap_decode(input,self.errors,decoding_table)[0]
UnicodeDecodeError: 'charmap' codec can't decode byte 0x8f in position 57: character maps to <undefined>
Why would this be? I am guessing it is something to do with how i am handling submitting the image file to the form but i'm stumped as to why. My relevant code is below:
form = browser.get_forms()
form = form[0]
image = os.path.dirname(os.path.realpath(__file__)) + r"\test.png"
form['file1'] = image
browser.submit_form(form, submit=form["add_photo_done"])
print(browser.parsed())
Edit:
I do not believe this is a repost of UnicodeDecodeError: 'charmap' codec can't decode byte X in position Y: character maps to as i am not reading any files in the code, the error seems to come while submitting the form. In any case I had seen this post already and i could not work out how to use it to solve my issue.
Figured out that i need to send an image object and not path to the image. solution code below if anyone is looking at this down the line:
image = open(os.path.dirname(os.path.realpath(__file__)) + r"\test.jpg", 'rb')