I have a lambda function that returns an image
When creating a new email with an image that its source is the lambda function i was able to see the image on all of the existing mail clients including linux and mac outlook
but on windows outlook it is not shown, I get a red X sign with the text "The picture can't be displayed"
any ideas what should be changed in the lambda's code in order to be able to see the image on Windows Outlook as well?
My Code:
from PIL import Image
from io import BytesIO
from flask import Flask, request, send_file
#app.route('/test')
def test():
img = Image.new('RGB', (100, 100))
imgByteArr = BytesIO()
format = 'JPEG'
mimetype = 'image/jpg'
img.save(imgByteArr, format=format, quality=90)
imgByteArr.seek(0)
return send_file(imgByteArr, mimetype=mimetype)
The Image code in the email:
<img style="display:block" src="my-lambda..." alt="" width="500" height="auto" border="0">
The Email on Windows outlook:
HTML messages are rendered in Outlook by Word, and (at least in the older versions), it does not support msg tags with inlined image data.
You'd need to add the image as an attachment, set its Content-ID MIME header, and refer to that image in the HTML body through <img src="cid:MyContenttId">
Related
I am trying to make Qr Codes using Python on a Django applicaiton using this code :
def generate_qr_code (reference):
qr = qrcode.QRCode(
version=1,
error_correction=qrcode.constants.ERROR_CORRECT_H,
box_size=10,
border=4,
)
qr.add_data(reference)
qr.make(fit=True)
img = qr.make_image(fill_color="black", back_color="white").convert('RGB')
filename = reference+".jpeg"
img.save("C:\\qrs\\"+filename)
Now, this function is called when I click on a "Generate Qr Code" Button. My problem is that I would like the Qr Code to be displayed on a new tab on my browser instead of it being saved as an image, as I only need to print them on paper at that moment and I have no need to keep the images.
Thank you for your help.
convert the image to base64 and show it in your html like this
import base64
b64 = base64.b64encode(image).decode("utf-8")
update:
ofc you don't need to save your image as png to use this feature, you can change the format in html and you can also change the image format without saving it to a file like this
After all, I managed to do so by using this simple line in my HTML:
<img id='barcode' src="https://api.qrserver.com/v1/create-qr-code/?data={{ref}}" alt="" title="{{ref}}" width="150" height="150"/>
You can use SVG format
import qrcode
import qrcode.image.svg
from io import BytesIO
def generate_qr_code (reference):
factory = qrcode.image.svg.SvgImage
qr_string = "sample text"
img = qrcode.make(qr_string, image_factory=factory, box_size=10)
stream = BytesIO()
img.save(stream)
context = {
'qrcode': stream.getvalue().decode()
}
return render(request, 'YOUR HTML.html', context)
and then you can use it in html file:
{{qrcode|safe}}
in my flask app after receiving POST request and running the code
image = request.files['image']
image variable have type
<FileStorage: 'image.png' ('image/png')>
how can i convert it to Pillow image or open with Image.open() ?
FileStorage is not image type but only wrapper on normal files like PNG/JPG/PDF/Excel/etc. which flask uses to keep information about original files and which gives you direct access to original file - probably as file handler - and Pillow can use it directly to read image (without saving to file, and without using io.Bytes to create file image in memory)
image = request.files['image']
img = Image.open(image) # load with Pillow
print(img.size) # show image size (width, height)
img = img.convert('L') # convert to greyscale
img.save('output.png') # save it
#draw = ImageDraw.Draw(img) # create object to draw figures or text on image
All modules/functions which can use file handler instead of filename (to read file) should read from FileStorage without problem.
EDIT:
Minimal working code - tested with images .png, .jpg, .webp
from flask import Flask, request, render_template_string
from PIL import Image
app = Flask(__name__)
#app.route('/', methods=['GET', 'POST'])
def index():
print(request.files)
if request.files:
image = request.files['image']
# pillow
img = Image.open(image)
print(img.size)
img = img.convert('L') # greyscale
img.save('output.png')
return render_template_string('''<form method="POST" enctype="multipart/form-data">
<input type="file" name="image"/>
<button type="submit">Submit</button>
</form>''')
if __name__ == '__main__':
app.run(debug=True)
#furas thank you! Your tip on image.seek(0) worked for me, this was the cause of my issue. My pointer was at the end of file when I was trying to access it after verifying.
I have a image in the server folder. In my do_GET() function which handles the Get request I would like to send a image back. I choose to use the self.wfile.write(''). Can anyone tell me how to include the source of the image in to the img tag? Or is there a better way to do this? Thanks.
You can include the "source" of an image in the img tag using a data URI like this:
<img alt="Embedded Image" src="data:image/png;base64,<your base64 encoding here>" />
Generate the base64 string using the base64 python standard lib:
import base64
with open("image.png", "rb") as image:
encoded_string = base64.b64encode(image.read())
I use Image.new create a image object in a django view,
I want to show it in webpages.
x = Image.new('RGB',(400,400))
return HttpResponse(x.show(), mimetype="image/png")
doesn't work.
How can I covert a image object to a image raw binary?
You can embed base64 images into an <img src= so you could try converting your PIL image to base64.
from PIL import Image
import StringIO
x = Image.new('RGB',(400,400))
output = StringIO.StringIO()
x.save(output, "PNG")
contents = output.getvalue().encode("base64")
output.close()
return HttpResponse('<img src="data:image/png;base64,' + contents + ' />')
You have 2 options:
Save your image in some place your web server can serve it
Encode it with base64 and show it directly
The first option is the prefered one. The code should be something like:
x = Image.new() # The same stuff than yours
x.save(MEDIA_ROOT + "/generated_images/the_name_of_the_image.jpg", "JPEG")
return HttpResponse(
"<img src="%s/%s />" % (MEDIA_URL, "/generated_images/the_name_of_the_image.jpg")
)
If you want, you can read that in base64 (see: Encoding an image file with base64)
And display it:
base64_img = get_base_64()
return HttpResponse('<img alt="Embedded Image" src="data:image/jpeg;base64," % base64_img />')
There is also a third way to accomplish this by having the view return the raw image so that the view's url can be referenced in the src attribute of the image tag.
Building on the examples others have used, the view that returns a dynamically generated image would look something like this:
from PIL import Image
import StringIO
def dynamic_image(request):
image = Image.new('RGB', (400, 400))
output = StringIO.StringIO()
image.save(output, 'PNG')
contents = output.getvalue()
output.close()
return HttpResponse(contents, content_type='image/png')
urls.py would reference this as:
urlpatterns = [
path('image', views.dynamic_image, name="dynamic_image")
]
Finally in the HTML, reference the view in the IMG tag:
<div>
<img src="{% url 'dynamic_image' %}" />
</div>
There is nothing wrong with the other approaches but they focus on returning HTML when Django views can return more than just HTML.
I had a problem before where it wouldn't show Chinese characters even when I specified #font-face to use a UTF-8 font. It turns out I cannot display images as well... so I seems like I am unable to get any of the files embeded into my pdf.
This is the code I use:
def render_to_pdf(template_src, context_dict):
"""Function to render html template into a pdf file"""
template = get_template(template_src)
context = Context(context_dict)
html = template.render(context)
result = StringIO.StringIO()
pdf = pisa.pisaDocument(StringIO.StringIO(html.encode("UTF-8")),
dest=result,
encoding='UTF-8',
link_callback=fetch_resources)
if not pdf.err:
response = http.HttpResponse(result.getvalue(), mimetype='application/pdf')
return response
return HttpResponse('We had some errors<pre>%s</pre>' % escape(html))
def fetch_resources(uri, rel):
import os.path
from django.conf import settings
path = os.path.join(
settings.STATIC_ROOT,
uri.replace(settings.STATIC_URL, ""))
return path
html
<img src="/static/images/bc_logo_bw_pdf.png" />
and
#font-face {
font-family: "Wingdings";
src: url("/static/fonts/wingdings.ttf");
}
I looked at the other quests on SO but it was no help. There are also no exceptions happening in the two functions. Also in fetch_resources function the path returned was the correct full path to the file i.e. /home/<user>/project/static/images/bc_logo_bw_pdf.png and /home/<user>/project/static/fonts/wingdings.ttf and I am at a loss as to what is wrong.
UPDATE
Everytime I create a pdf, I get this message on the console
No handlers could be found for logger "ho.pisa"
could this be related?
UPDATE #2
The font works now I made a dumb mistake... The font I was using did not have the Chinese unicode. But I still cannot embed any images onto the pdf, be it jpeg, gif or png.
I have finally solved the problem I was having... it turns out it doesn't work if I set the body's height with css... once I removed that line the image was loading perfectly...
For me (django 1.4, python 2.7 pisa==3.0.33), If I put the full path of image instead of relative, it works for me.
Try doing the same.
Everything looks better . Try once with JPG image file. In my case PNG file was also not working.
<img src="/static/images/<name>.jpg" />
without width and height attribute image will not work. add width and height attribute.
<img src="{% static 'images/logo.png' %}" alt="image" width="200" height="150" />
this fix works for me.
I have the same problem here. Don't give up with XHTML2PDF Pisa.
Pisa use PIL for generate PDF and use lib zip decoder to inserting images.
You should check if your PIL already installed properly with zip decoder, fonts and several components
I have solve this problem by installing PIL with zip decoder.
http://obroll.com/install-python-pil-python-image-library-on-ubuntu-11-10-oneiric/
If you need more detail information, you can read my article here :
http://obroll.com/how-to-load-images-files-style-css-in-pdf-using-pisa-xhtml2pdf-on-django/