POST an image and display it in dashboard in Node-red - python

My goal is to send a picture via POST request in Python and to display it in a dashboard in Node Red, but I'm stuck in the step of reading the image once it's been sent.
This is the piece of code I'm using to send the file:
directory = os.path.join(DIRECTORY_IMAGES, id)
files = {'image': open(directory,'rb')}
requests.post('http://XXX.XXX.X.XX:1880/IMAGE', files = files)
Once in Node-red, the blocks I'm using are the following:
The message is received, but I'm unable to get the picture out of it. As I've read in other posts the msg.payload is set to req.files[0].buffer, encoded as Base64 and displayed using <img width="16" height="16" src="files:image;base64,{{msg.payload}}" /> in a template, but that does not display the image.
[{"id":"797939a8.a91a58","type":"http response","z":"ddfa6621.2e7168","name":"","statusCode":"","headers":{},"x":1290,"y":2280,"wires":[]},{"id":"d5b145ce.a712f8","type":"ui_template","z":"ddfa6621.2e7168","group":"9beeae56.34305","name":"Display image","order":4,"width":"7","height":"6","format":"<img width=\"16\" height=\"16\" src=\"files:image;base64,{{msg.payload}}\" />\n","storeOutMessages":true,"fwdInMessages":true,"templateScope":"local","x":1680,"y":2220,"wires":[[]]},{"id":"5e30e496.958b9c","type":"change","z":"ddfa6621.2e7168","name":"","rules":[{"t":"set","p":"payload","pt":"msg","to":"req.files[0].buffer","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":1300,"y":2220,"wires":[["2f260e60.d12642"]]},{"id":"2f260e60.d12642","type":"base64","z":"ddfa6621.2e7168","name":"Encode","x":1500,"y":2220,"wires":[["d5b145ce.a712f8"]]},{"id":"18c71628.986f4a","type":"http in","z":"ddfa6621.2e7168","name":"","url":"IMAGE","method":"post","upload":true,"swaggerDoc":"","x":1050,"y":2220,"wires":[["5e30e496.958b9c","797939a8.a91a58"]]},{"id":"9beeae56.34305","type":"ui_group","z":"","name":"Última pierna procesada","tab":"223d38a0.9cbaa8","order":8,"disp":true,"width":"7","collapse":false},{"id":"223d38a0.9cbaa8","type":"ui_tab","z":"","name":"CALIDAD PULPAS CINTA 0","icon":"dashboard","disabled":false,"hidden":false}]
What am I missing?

The img src tag should start with data:image/jpeg;base64, (assuming a JPEG image)
You should swap the image/jpeg for the mime type of the image, e.g. image/png
[{"id":"9dff2c2e.66ea1","type":"http response","z":"c09a8743.c89388","name":"","statusCode":"","headers":{},"x":390,"y":180,"wires":[]},{"id":"68e0a720.f29498","type":"ui_template","z":"c09a8743.c89388","group":"efcf5006.15dae","name":"Display image","order":4,"width":"7","height":"6","format":"<img width=\"16\" height=\"16\" src=\"data:image/jpeg;base64,{{msg.payload}}\" />\n","storeOutMessages":true,"fwdInMessages":true,"templateScope":"local","x":800,"y":120,"wires":[[]]},{"id":"2fb71bea.a5d1e4","type":"http in","z":"c09a8743.c89388","name":"","url":"IMAGE","method":"post","upload":true,"swaggerDoc":"","x":210,"y":120,"wires":[["9dff2c2e.66ea1","a87b8d6.a9b0c7"]]},{"id":"a87b8d6.a9b0c7","type":"change","z":"c09a8743.c89388","name":"","rules":[{"t":"set","p":"payload","pt":"msg","to":"req.files[0].buffer","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":420,"y":120,"wires":[["4bcddbb.38c2624"]]},{"id":"4bcddbb.38c2624","type":"base64","z":"c09a8743.c89388","name":"Encode","x":620,"y":120,"wires":[["7d7586e7.205398","68e0a720.f29498"]]},{"id":"7d7586e7.205398","type":"debug","z":"c09a8743.c89388","name":"","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":790,"y":60,"wires":[]},{"id":"efcf5006.15dae","type":"ui_group","z":"","name":"Última pierna procesada","tab":"65324def.436554","order":8,"disp":true,"width":"7"},{"id":"65324def.436554","type":"ui_tab","z":"","name":"CALIDAD PULPAS CINTA 0","icon":"dashboard"}]
triggered with the following python:
import requests
files = {'image': open('/Users/hardillb/temp/photos/DSC_7188.JPG', 'rb')}
requests.post('http://localhost:1880/IMAGE', files = files)

Related

How to add multiple embed images in a body email using exchangelib

I have a message in HTML format. I need to reply to this email, keeping all the pictures from the previous email.
I have all the pictures from the email saved, and now I need to add them back. How to do it?
exchabgelib has instructions for this:
from exchangelib import HTMLBody
message = Message()
logo_filename = 'logo.png'
with open(logo_filename, 'rb') as f:
my_logo = FileAttachment(
name=logo_filename, content=f.read(), is_inline=True,
content_id=logo_filename
)
message.attach(my_logo)
# Most email systems
message.body = HTMLBody(
'<html><body>Hello logo: <img src="cid:%s"></body></html>' % logo_filename
)
If the new email must also be in HTML format, then attach the images one by one and add an <img> tag for each image you have attached. Otherwise, just attach the images and compose the email in plain text.

Render image from request in bottle

My intention is to upload an image and do some image processing. For now, I intend to render the uploaded image.
I used the code here to build my front end and I wrote the backend in python using bottle, which is as follows:
#route('/test', method='POST')
def serve_image():
# import pdb; pdb.set_trace()
image = Image.open(request.body)
image.show()
I get an errors as follows
OSError: cannot identify image file <_io.BytesIO object at
0x0000017386B53A40>
What am I missing?
EDIT:
When I print the whole request, this is what I get
< http://localhost:8080/test>
That tutorial is not very comprehensive, but the full documentation is more useful:
The image data is uploaded as part of a standard multipart form post, and included as a form element named webcam.
So rather than trying to pass the whole request body to Pillow, you need to pass just that element, using the request.files multidict, and accessing its file attribute to get the buffer:
image = Image.open(request.files['webcam'].file)

Python HTML - Embedded email images are blank

I'm sending emails using smtplib and I'm generating an email signature that has embedded images. I used https://www.base64-image.de/ to convert several images to base64 strings, and I'm using those encoded strings like this, as part of a MIMEMultipart('mixed') message:
body = """\
<html>
...
<img src="%s" width = "32" height = "32">
<img src="%s" width = "32" height = "32">
<img src="%s" width = "32" height = "32">
...
</html>""" % (encoded_string1, encoded_string2, encoded_string3)
Example of what the string variables look like:
encoded_string1 = 'data:image/png;base64,iVBORw...'
Everything in the email is sent and formatted correctly. The images are in the correct places and are the correct size. But the images in the email are blank. There is just a border around where the image should be.
I can't figure out why this is happening. https://codebeautify.org/base64-to-image-converter can decode base64 strings to an image, and I've tested my base64 strings to make sure they're correct, which they are.
If I use a website where the images are saved as the src in the img tag, it shows up correctly in the email. I don't want to do this as I don't have control over the site that hosts the images, and I don't want to create my own site to host the images if I can avoid it.
Does anyone know why they're showing up as blank in the email once it's sent? Thanks!
May be problem with client-side support
Send a base64 image in HTML email

Displaying image in template with Flask?

So I am hosting some user-uploaded images on my site. I want to have an html page that displays the image inline, and some data about it on the side, etc. I've set up my app with two handlers, one that displays the image on the page that uses a url_for to get the url for the raw image(e.g. i.mysite.com/image.jpg). It displays on the page fine, but takes forever to load. When I remove this function and just generate a URL for the image alone without the page, it loads instantly. Is this just a flask thing that will be remedied in a production environment with a real webserver, or is there another way I should be doing this? The images are not in the /static folder, they are in their own folder. I get the url for the raw image link in the handler for the function that displays the page with the image on it, and pass that as a path to the template.
#app.route('/<filename>', subdomain='i')
def uploaded_image(filename):
return send_from_directory(app.config['IMAGE_FOLDER'], filename)
#app.route('/<tag>/', subdomain='i', methods=['GET'])
def display_image(tag):
file = Storedfile.query.filter_by(routing_id=tag).first()
filename = file.name
return render_template("image-page.html", source=url_for('uploaded_image', filename=filename))
Like I said it displays the image fine, but takes forever to load, and when I inspect the image on the page with FF's dev tools, instead of seeing an actual URL, I see something like
<img src="/pyhE4eJ.jpg"></img>
For the other links, I get actual URLS that are made from functions, like
Shouldn't the source for the image be looking like this too?

TurboMail not adding Content-ID when embedding images

My bad. Postmark does not support inline images apparently. Solved by changing smtp-mail provider.
I'm trying to send e-mails with TurboMail using pylons.
Everything works fine, except for using embedded images in html-content. It seems that the Content-ID header for each image is being lost somewhere along the way.
This is my code:
def sendMail(to,subject,html_content,plain_content,images):
from turbomail import Message as Mail
mail = Mail(to=to,subject=subject)
mail.plain = plain_content
mail.rich = html_content
for cid,path in images.iteritems():
mail.embed(path,cid)
mail.send()
In my tests the html content is:
<html>
<header/>
<body>
<h1>Send images using TurboMail</h1>
<img src="cid:img0" />
</body>
</html>
And the images dict:
{"img0":"path/to/img0"}
When you pass in both a filename and a cid, TurboMail ignores the cid and uses the basename of the file instead. I suspect your filenames have extensions and your cids do not:
{"img0":"path/to/img0.png"}
If so, the images are embedded with a cid of img0.png instead.
You could pass in an open image file instead; TurboMail will then not ignore the name:
def sendMail(to,subject,html_content,plain_content,images):
from turbomail import Message as Mail
mail = Mail(to=to,subject=subject)
mail.plain = plain_content
mail.rich = html_content
for cid,path in images.iteritems():
mail.embed(open(path, 'rb'), cid)
mail.send()
I'd use marrow.mailer instead; it's the new name for the same package but the .embed method has been made a little saner in it's handling of embedded images and cids.
an earlier revision of this answer had marrow and TurboMail confused, referring to the marrow .embed signature instead.
Apparently, Postmarkapp does not support inline images.

Categories

Resources