I have a webpage generated from python that works as it should, using:
print 'Content-type: text/html\n\n'
print "" # blank line, end of headers
print '<link href="default.css" rel="stylesheet" type="text/css" />'
print "<html><head>"
I want to add images to this webpage, but when I do this:
sys.stdout.write( "Content-type: image/png\n\n" + file("11.png","rb").read() )
print 'Content-type: text/html\n\n'
print "" # blank line, end of headers
print '<link href="default.css" rel="stylesheet" type="text/css" />'
...
All I get is the image, then if I place the image code below my html/text header all I get is the text from the image, ie:
<Ï#·öÐδÝZºm]¾|‰k×®]žòåËÛ¶ÃgžyFK–,ÑôéÓU½zuIÒ}÷ݧ&MšH’V¯^?üð¼1±±±zýõ×%IñññÚºu«*W®¬wß}W.—K3gÎÔÌ™ÿw‹Ú””I’¹w¤¥hdÒd½q÷X•Šˆ²m¿þfïÞ½*]º´éÈs;¥¤¤Ø¿ILLÔˆ#rÊ
Also, if I try:
print "<img src='11.png'>"
I get a broken image in the browser, and browing directly to the image produces a 500 internal server error, with my apache log saying:
8)Exec format error: exec of './../../11.png' failed Premature end of script headers: 11.png
You can use this code to directly embed the image in your HTML:
Python 3
import base64
data_uri = base64.b64encode(open('Graph.png', 'rb').read()).decode('utf-8')
img_tag = '<img src="data:image/png;base64,{0}">'.format(data_uri)
print(img_tag)
Python 2.7
data_uri = open('11.png', 'rb').read().encode('base64').replace('\n', '')
img_tag = '<img src="data:image/png;base64,{0}">'.format(data_uri)
print(img_tag)
Alternatively for Python <2.6:
data_uri = open('11.png', 'rb').read().encode('base64').replace('\n', '')
img_tag = '<img src="data:image/png;base64,%s">' % data_uri
print(img_tag)
Images in web pages are typically a second request to the server. The HTML page itself has no images in it, simply references to images like <img src='the_url_to_the_image'>. Then the browser makes a second request to the server, and gets the image data.
The only option you have to serve images and HTML together is to use a data: url in the img tag.
You can't just dump image data into HTML.
You need to either have the file served and link to it or embed the image encoded in base64.
Related
My goal is to add an image (from local .png file) to an Outlook MailItem using Python.
I have read answers to similar questions on SO (mostly using VBA), but the issue I have is that the mail looks fine (I can see the image) before I send it (and when I look in my Sent Items folder), but when it is received at the other end, the image is broken.
If I manually insert the image in a message (using Insert / Picture / From this Device from the Outlook menu) the email arrives fine, with the image displayed.
Here is the basic code I am using (based mostly on VBA examples):
import win32com.client as wc
def main():
outlook = wc.Dispatch("Outlook.Application")
#Create a new mail item
msg = outlook.CreateItem(0)
#Set some properties
msg.BodyFormat = 2
msg.Subject = 'Here is my chart'
msg.Recipients.Add('xxx#yyy.com')
#Add an attachment, with position 0
imageFile = 'C:\\Temp\\myplot.png'
ats = msg.Attachments
att = ats.Add(imageFile,1,0)
#Set the HTMLBody
msg.HTMLBody = '<img src="cid:{0:}" width=200 height=200>'.format(att.FileName)
#Send
msg.Send()
main()
This is what I see in my Sent Items folder:
The HTML in my sent item (using View Source) is this:
<img src="cid:myplot.png" width=200 height=200>
But this is what arrives:
The HTML in the body at the destination is this:
<html><head>
<meta http-equiv="Content-Type" content="text/html; charset=us-ascii">
</head>
<body>
<img src="cid:AD1B7014D243624CA83F873A11053F18#GBRP123.PROD.OUTLOOK.COM" width="200" height="200">
</body>
</html>
When I manually insert the image, the received HTML is much longer (so I won't include it all here), but the 'img' tag is here (and this matches what is in the Sent Items folder):
<img width="614" height="461" style="width:6.3958in;height:4.802in" id="Picture_x0020_1" src="cid:image001.png#01D736CD.72206440" alt="Chart, line chart Description automatically generated">
I would appreciate any insights on this! (Sadly Outlook won't let me record a macro to see what the manual process is doing). I have seen one example (from C#) where the SetProperty() method is used on the MailItem to add other items that are not in the Outlook object model (schema, context id), together with a newly created Guid, but is this really necessary?
Using Microsoft 365, Outlook version 2105, Beta Channel
Create an attachment and set the PR_ATTACH_CONTENT_ID property (DASL name "http://schemas.microsoft.com/mapi/proptag/0x3712001F") using Attachment.PropertyAccessor.SetProperty.
Your HTML body (MailItem.HTMLBody property) would then need to reference that image attachment through the cid:
img src="cid:xyz"
where xyz is the value of the PR_ATTACH_CONTENT_ID property.
Look at an existing message with OutlookSpy (I am its author) - click IMessage button.
attachment = mailitem.Attachments.Add("c:\temp\MyPicture.jpg");
attachment.PropertyAccessor.SetProperty("http://schemas.microsoft.com/mapi/proptag/0x3712001F", "MyId1");
mailitem.HTMLBody = "<html><body>Test image <img src=""cid:MyId1""></body></html>";
I have a Flask server and I want to render a base64 image in HTML page.
Flask Code:
new_image_string = base64.b64encode(buff.getvalue()).decode("utf-8")
return render_template('perspective_result.html', img_data=new_image_string)
HTML CODE:
<img src="data:image/jpeg;base64,+img_data" alt="img_data" id="imgslot"/>
I am getting the below error from browser console:
GET data:image/jpeg;base64,+img_data 0 ()
Where did I go wrong?
<img src="data:image/jpeg;base64,{{ img_data }}" alt="img_data" id="imgslot"/>
This is the way we can solve this.
1.First Add A empty Image Tag Without A Source
2.Then With Javascript preprocess the base64 data string
3.update the Image src with updated base64 data
<img src="" id="img" alt="Chart" height="100" width="100">
<script>
data = "{{data}}"
data = data.replace("b'", "") //to get rid of start curly brace code
data = data.replace("'", "") //to get rid of end curly bracecode
document.getElementById("img").src = "data:image/png;base64,"+data; // set src
</script>
I'm trying to show some badge images I made for a RANK APP I've been working for. It's 10 images that should be shown specific for each driver.
I'm not an expert on coding, but I keep searching and studying ways to solve the problem I've been through.
I firstly tried to send base64 images from the API to the browser, using this code:
<!-- language: python -->
for img in imglist: #loop for creating a list of base64 images from a list of image dir.
imgcode = base64.encodestring(open(imgdir + img,"rb").read())
imgcodelist.append(imgcode)
for driver in sortdriverList: #loop for taking drivers points and turn it into RANK img
if (driver['Races'] < 21):
driver['Rank'] = str(imgcodelist[9])
[...]
The second loop is longer than that, stil what I've shown to you above makes any driver that wasn't participating in more than 21 races, be part of a 'NON CLASSIFIED' badge.
I used AngularJS to try to show the base64 image using the code below.
'<html>'
<td><img src="data:image/png;base64,{{ '{{driver.Rank}}'}}"></td>
[driver.Rank] should be the base64 code string. When I run the app, the image is not shown, instead I see the very code of the image inside the table =/
Then I tried to turn [driver.Rank] into a dir string for "img src=", using the codes below.
<!-- language: python -->
imglist = ["notclassified.png", etc...]
imgdir = "static/images/"
for item in sortdriverList:
if (item['Races'] < 21):
item['Points'] = imgdir + imglist[9]
and in my HTML I changed the img src to:
'<html>'
<img src= {{ '{{driver.Rank}}' }}>
and now it shows the directory of the images.
I've been searching for CSS ways to make it possible.
I coudn't find a solution yet.
It's hard to tell what's going on since only segments are pasted, but I'm guessing it has to do with how you are escaping the code. Maybe you could paste the generated code in chrome.
Sometimes seeing a working example helps.
angular.module('App', [])
.controller('DriverCtrl', DriverCtrl);
function DriverCtrl($scope) {
// base64 encode 1x1 black pixel
this.Rank = 'R0lGODlhAQABAIAAAAUEBAAAACwAAAAAAQABAAACAkQBADs=';
}
<div ng-app="App">
<div ng-controller="DriverCtrl as driver">
<div>Rank: {{driver.Rank}}</div>
<span>Image:</span>
<img ng-src="data:image/png;base64,{{driver.Rank}}">
</div>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
I try to use Brython. I have a Python script (test.py) and I would like to display the result of this script in the browser.
I have tried :
<html>
<head>
<script src="brython.js"></script>
</head>
<body onload="brython()">
<script type="text/python" src="test.py"></script>
</body>
</html>
and my script is :
x = int(input("Value: "))
x = pow(x,2)
print("Result: " + str(x))
Unfortunately, I cannot display the result in the browser. Is there something missing ?
In Brython, print displays in the browser console.
If you want to write the result in the HTML document:
from browser import document
x = int(input("Value: "))
x = pow(x, 2)
document <= "Result: " + str(x)
[edit] Another option is to set sys.stdout to an object with a write() method, for instance document in module browser :
from browser import document
import sys
sys.stdout = document
print("Hello", "world !")
Add an id='fish' whatever for tag and then overwrite it in python:
<body id='fish' onload='brython()'>
and then:
d = document['fish']
d.clear()
d <= "Result: %s" % str(x)
Note that you need to call element .clear() first, <= is the same as Javascript .appendChild(), see the documentation: https://brython.info/static_doc/en/cookbook/content_in_div.html
If you want to see it in proper XHTML page, don't replace the whole body but just one div-element/tag for example. Or overwrite the whole body with all needed XHTML tags.
I am trying to display the contents of /etc/postfix/transport.in in a <div> via python & cgi. When I run the script from the command line it works as I would expect, however, when called from the webpage it does not display the file contents. This is what I have in my CGI:
#!/usr/bin/env python
import cgi, os.path
# fileName = "/etc/postfix/transport.in"
form = cgi.FieldStorage()
fileName = form['file'].value
def safePlainText(s):
newString = s.replace('&', '&').replace('<', '<')
return newString
def fileLinesToHTMLLines(fileName):
safeLines = list()
if os.path.exists(fileName): # test if the file exists yet
lines = fileToStr(fileName).splitlines()
for line in lines:
safeLines.append(safePlainText(line))
return safeLines
def fileToStr(fileName):
fin = open(fileName);
contents = fin.read();
fin.close()
return contents
lines = fileLinesToHTMLLines(fileName)
print "Content-type:text/html\r\n\r\n"
print "<html>"
print "<head>"
print "<title>Data File %s</title>" % fileName
print "</head>"
print "<body>"
print "<ul>"
for line in lines:
print "<li> %s </li>" % str(cgi.escape(line))
print "</ul>"
print "</body>"
print "</html>"
Everything (HTML Tags incl. title) comes through as expected with the exception of the lines of the file I am trying to display. Firebug shows the response from the server as being:
<html>
<head>
<title>Data File transport.in</title>
</head>
<body>
<ul>
</ul>
</body>
</html>
However if I run the script from the command line I get:
# sudo -u apache ./test3.py
Content-type:text/html
<html>
<head>
<title>Data File /etc/postfix/transport.in</title>
</head>
<body>
<ul>
<li> host.domain.com relay:[mailhub.domain.corpnet1] </li>
<li> * relay:[host.mailrelay.com] </li>
</ul>
</body>
</html>
I am sure that it is something simple, but for the life of me I cannot figure it out...
I am running Python 2.7.5 / Apache 2.4.6 on RHEL7.
The "Data File" are different.
Data File transport.in
Data File /etc/postfix/transport.in
Please paste the url when you called from the webpage.