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.
!wget https://github.com/lazyprogrammer/machine_learning_examples/blob/master/cnn_class/lena.png
from PIL import Image
im =Image.open('lena.png')
UnidentifiedImageError Traceback (most recent call last)
in ()
----> 1 im =Image.open('lena.png')
/usr/local/lib/python3.6/dist-packages/PIL/Image.py in open(fp, mode)
2929 warnings.warn(message)
2930 raise UnidentifiedImageError(
-> 2931 "cannot identify image file %r" % (filename if filename else fp)
2932 )
2933
UnidentifiedImageError: cannot identify image file 'lena.png'
The link you are using to wget is all wrong. You are actually sending a GET request to the html file instead of the image.
Here's the actual image link for you :)
https://raw.githubusercontent.com/lazyprogrammer/machine_learning_examples/master/cnn_class/lena.png
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'})
This is a basic script that should insert a watermark image on the first page of a PDF and save it under a new name.
I could do the same with the same files in pdfrw, but I'm stuck with PyMuPDF (which I would prefer to use...).
The py file is in the same folder with the pdf and the png.
import fitz
input_file = "sample.pdf"
output_file = "sample_stamped.pdf"
stamp = "watermark.png"
doc = fitz.open(input_file)
rect = fitz.Rect(0, 0, 100, 100)
pix = fitz.Pixmap(stamp)
page = doc[0]
page.insertImage(rect, pixmap = pix, overlay = True)
doc.save(output_file)
I'm getting this error msg:
Traceback (most recent call last):
File "D:/Google Drive/Python/PDF/pdfstamp.py", line 14, in <module>
doc.save(output_file)
File "D:\Python\lib\site-packages\fitz\fitz.py", line 2411, in save
return _fitz.Document_save(self, filename, garbage, clean, deflate, incremental, ascii, expand, linear, pretty, decrypt)
RuntimeError: not a dict (array)
Thanks in advance for any help.
It seems the task is easy but...
I have simple PIL.Image object. How to make Cherrypy response with this image dynamically?
def get_image(self, data_id):
cherrypy.response.headers['Content-Type'] = 'image/png'
img = PIL.Image.frombytes(...)
buffer = io.StringIO()
img.save(buffer, 'PNG')
return buffer.getvalue()
This code gives me:
500 Internal Server Error
The server encountered an unexpected condition which prevented it from fulfilling the request.
Traceback (most recent call last):
File "C:\Users\Serge\AppData\Local\Programs\Python\Python36\lib\site-packages\cherrypy\_cprequest.py", line 631, in respond
self._do_respond(path_info)
File "C:\Users\Serge\AppData\Local\Programs\Python\Python36\lib\site-packages\cherrypy\_cprequest.py", line 690, in _do_respond
response.body = self.handler()
File "C:\Users\Serge\AppData\Local\Programs\Python\Python36\lib\site-packages\cherrypy\_cpdispatch.py", line 60, in __call__
return self.callable(*self.args, **self.kwargs)
File "D:\Dev\Bf\webapp\controllers\calculation.py", line 69, in get_image
img.save(buffer, 'PNG')
File "C:\Users\Serge\AppData\Local\Programs\Python\Python36\lib\site-packages\PIL\Image.py", line 1930, in save
save_handler(self, fp, filename)
File "C:\Users\Serge\AppData\Local\Programs\Python\Python36\lib\site-packages\PIL\PngImagePlugin.py", line 731, in _save
fp.write(_MAGIC)
TypeError: string argument expected, got 'bytes'
Can someone help me please?
Use io.BytesIO() instead of io.StringIO(). (From this answer.)