使用javascript从python CGI返回图像 [英] Return Image from python CGI using javascript
问题描述
我使用Python CGI创建一个显示标题,下拉菜单和图像的网页。我希望能够从下拉菜单中选择一个选项(希望摆脱提交,以及选择选项时运行),触发我的Python代码(runthis.py)并更新图像该网页。我希望在不打开新选项卡的情况下执行此操作,并希望不刷新页面。目前我运行这个.py文件来获得我的html:
#!C:\Python27\python
printContent-type:text / html
print
print< html>
打印< head>
打印<标题>标题标题< /标题>
打印< / head>
print'''< body bgcolor =#ccffcc>'''
print'''< h1 align =center>页面标题< / h1> '''
print'''< form action =/ cgi-bin / dropdown.pymethod =posttarget =_ blank>'''
print '''< select name =dropdown>'''
print'''< option value =Option1selected> Option1< / option>'''
print''' < option value =Option2selected> Option2< / option>'''
print< / select>
print'''< input type =submitvalue =Submit/>'''
print< / form>
print< img src = /test.png>
打印< / body>
打印< / html>
当我点击提交时,会打开一个新标签,显示相同的页面布局,图像(例如同样的一个)。这是通过cgi-bin中的 dropdown.py
文件完成的:
#!C:\Python27\python
import cgi,cgitb,os
cgitb.enable()
os.environ ['HOME'] ='C:\python_cgi'
import matplotlib
matplotlib.use('Agg')
$ b $ form = cgi.FieldStorage()
if form.getvalue('dropdown'):
subject = form.getvalue('dropdown')
else:
subject =Not Entered
from matplotlib.figure import图
from matplotlib.backends.backend_agg import FigureCanvasAgg
import StringIO
import msvcrt,sys,urllib,base64
fig =图(figsize = [4,4])
ax = fig.add_axes([.1,.8,.8])
ax.scatter([1,2],[ 3,4])
canvas = FigureCanvasAgg(fig)
imgdata = StringIO.StringIO()
fig.savefig(imgdata,format ='png')
imgdata.seek(0)
uri ='data:image / png; base64,'+ urllib.quote(base64.b64encode(imgdata.buf))
pr intContent-Type:text / html
print
print\
< html>
< head>
< title>标题标题< / title>
< / head>
< body>
< body bgcolor =#ccffcc>
< h1 align =center>页面标题< / h1>
< form action =/ cgi-bin / dropdown.pymethod =posttarget =_ blank>
< select name =dropdown>
< option value =选项1选择>选项1< /选项>
< option value =Option2selected> Option2< / option>
< / select>
< input type =submitvalue =Submit/>
< / form>
< img src =%s />
< / body>
< / html> %uri
回顾一下 - 我只是想改变当前的图片/图片而不是打开一个全新的页面,我的直觉告诉我要使用javascript(我什么也不知道)。有没有人有一个代码块的建议,我需要进入这样的事情?
谢谢!
编辑
根据下面的评论,我试图实现这个html文件:
< html>
< head>
< title>标题标题< / title>
< script src =// ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min。 js>< / script>
< / head>
< body>
< script>
function changeImage(imgName )
{
jQuery.get('/ cgi-bin / dropdown.py',function(data){
image = document.getElementById('imgDisp');
image .src = data;
})
}
< / script>
& lt; body bgcolor =#ccffcc>
< h1 align =center>页面标题< / h1>
< select name =dropdownonchange =changeImage(this.value)>
< option value =Option1> Option1< / option>
< option value =Option2> Option2< / option>
< / select>
< img id =imgDispsrc =/ test.png/>
< / body>
< / html>
这会正确加载我的页面,但从下拉列表中选择时没有任何反应。我希望图像会改变。我的dropdown.py代码现在看起来像:
#!C:\Python27\python
import cgi,cgitb,os
cgitb.enable()
os.environ ['HOME'] ='C:\python_cgi'
import matplotlib
matplotlib.figure中的matplotlib.use('Agg')
图matplotlib.backends.backend_agg中的
导入FigureCanvasAgg
导入StringIO
import msvcrt,sys,urllib,base64
$ b $ fig = figure(figsize = [4,4])
ax = fig.add_axes([。1,.1 ,. 8,.8])
ax.scatter([1,2],[3,4])
canvas = FigureCanvasAgg(fig)
imgdata = StringIO.StringIO )
fig.savefig(imgdata,format ='png')
imgdata.seek(0)
uri ='data:image / png; base64,'+ urllib。 quote(base64.b64encode(imgdata.buf))
return uri
我还没有得到了url参数方法 - 但不知道如何做。任何更多的建议将不胜感激!
回应您编辑的问题,解决方案实际上可以更简单:
function changeImage(imgName){
jQuery.get('/ cgi-bin / dropdown.py',function(data) {
image = document.getElementById('imgDisp');
image.src = data;
})
}
在这里,您正在向您的Python脚本发出异步请求,并等待返回一些数据。但是,您可以将您的Python脚本视为一种独立的服务,它可以映射,也就是说,可以为(动态生成的)图像提供一组独特的参数。这需要您的Python脚本将图像输出到浏览器,而不是通过CGI返回图像数据:
imgdata = StringIO.StringIO()
fig.savefig(imgdata,format ='png')
imgdata.seek(0)
沿着这些线的东西
printContent-Type:img / png\\\
imgdata.seek(0)
print imgdata.read()
一旦您确信您的Python脚本的HTTP请求提供了有效的PNG,您的前端代码只需更新 src
您显示的图片的属性:
function changeImage(imgName){
var url =http:// localhost:8000 / cgi-bin / dropdown.py?image =+ imgName;
var img = jQuery('#imgDisp');
img.src = url;
当 img
元素被赋予一个新的 src
值,浏览器将自动向该URL发出请求并尝试检索图像,该图像将加载到您的页面上,替换之前的图像。然而,你将不得不修改你的Python脚本,以期望一个名为 image
的请求参数,它包含一个字符串。
#例子CGI脚本
if __name__ = =__main__:
params = cgi.FieldStorage()
如果参数中有image:
img = params ['image']
#生成图像并输出使用正确的标题
else:
#处理异常
printContent-Type:text / html\\\
print< html>< body> < / body>< / html>
是一个很好的资源,您可以查看: http://lost-theory.org/python/dynamicimg .html
I am using Python CGI to create a webpage that shows a title, dropdown menu and image. I would like to be able to select an option from the dropdown menu (would love to get rid of "submit" as well and just run when an option is chosen), trigger my python code (runthis.py) and update the image on the webpage. I want to do this WITHOUT opening new tabs and hopefully without refreshing the page. Currently I run this .py file to get my html:
#!C:\Python27\python
print "Content-type: text/html"
print
print "<html>"
print "<head>"
print "<title>Tab Title</title>"
print "</head>"
print '''<body bgcolor="#ccffcc">'''
print '''<h1 align="center">Page Heading</h1>'''
print '''<form action="/cgi-bin/dropdown.py" method="post" target="_blank">'''
print '''<select name="dropdown">'''
print '''<option value="Option1" selected>Option1</option>'''
print '''<option value="Option2" selected>Option2</option>'''
print "</select>"
print '''<input type="submit" value="Submit"/>'''
print "</form>"
print "<img src = /test.png>"
print "</body>"
print "</html>"
When I click "submit", a new tab will open showing the same page layout, just a different image (same one for example's sake). This is done through my dropdown.py
file in cgi-bin:
#!C:\Python27\python
import cgi,cgitb,os
cgitb.enable()
os.environ['HOME']='C:\python_cgi'
import matplotlib
matplotlib.use('Agg')
form = cgi.FieldStorage()
if form.getvalue('dropdown'):
subject = form.getvalue('dropdown')
else:
subject = "Not Entered"
from matplotlib.figure import Figure
from matplotlib.backends.backend_agg import FigureCanvasAgg
import StringIO
import msvcrt,sys, urllib, base64
fig = Figure(figsize=[4,4])
ax = fig.add_axes([.1,.1,.8,.8])
ax.scatter([1,2],[3,4])
canvas = FigureCanvasAgg(fig)
imgdata = StringIO.StringIO()
fig.savefig(imgdata, format='png')
imgdata.seek(0)
uri = 'data:image/png;base64,' + urllib.quote(base64.b64encode(imgdata.buf))
print "Content-Type: text/html"
print
print """\
<html>
<head>
<title>Tab Title</title>
</head>
<body>
<body bgcolor="#ccffcc">
<h1 align="center">Page Heading</h1>
<form action="/cgi-bin/dropdown.py" method="post" target="_blank">
<select name="dropdown">
<option value="Option1" selected>Option1</option>
<option value="Option2" selected>Option2</option>
</select>
<input type="submit" value="Submit"/>
</form>
<img src = %s/>
</body>
</html> """ % uri
To recap -- I just want to change the picture/image on the current page rather than opening up a whole new page. My gut tells me to use javascript (which I know nothing about). Does anyone have a suggestion on a code block that I need to enter to do such a thing?
Thanks!
EDIT
Per the comments below, I am trying to implement this html file:
<html>
<head>
<title>Tab Title</title>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js" ></script>
</head>
<body>
<script>
function changeImage(imgName)
{
jQuery.get('/cgi-bin/dropdown.py', function(data) {
image = document.getElementById('imgDisp');
image.src = data;
})
}
</script>
<body bgcolor="#ccffcc">
<h1 align="center">Page Heading</h1>
<select name="dropdown" onchange="changeImage(this.value)">
<option value="Option1">Option1</option>
<option value="Option2">Option2</option>
</select>
<img id="imgDisp" src="/test.png" />
</body>
</html>
This loads my page correctly but nothing happens when I make a selection from the dropdownlist. I was hoping the image would change. My "dropdown.py" code now looks like:
#!C:\Python27\python
import cgi,cgitb,os
cgitb.enable()
os.environ['HOME']='C:\python_cgi'
import matplotlib
matplotlib.use('Agg')
from matplotlib.figure import Figure
from matplotlib.backends.backend_agg import FigureCanvasAgg
import StringIO
import msvcrt,sys, urllib, base64
fig = Figure(figsize=[4,4])
ax = fig.add_axes([.1,.1,.8,.8])
ax.scatter([1,2],[3,4])
canvas = FigureCanvasAgg(fig)
imgdata = StringIO.StringIO()
fig.savefig(imgdata, format='png')
imgdata.seek(0)
uri = 'data:image/png;base64,' + urllib.quote(base64.b64encode(imgdata.buf))
return uri
I haven't gotten to the url parameter approach yet -- not sure how that is done. Any more advice would be greatly appreciated!
In response to your edited question, the solution can actually be simpler:
function changeImage(imgName) {
jQuery.get('/cgi-bin/dropdown.py', function(data) {
image = document.getElementById('imgDisp');
image.src = data;
})
}
Here you are making an asynchronous request to your Python script, and waiting for some data to be returned. However, you could consider your Python script a standalone service that maps, so to speak, a unique set of parameters to a (dynamically generated) image. This requires your Python script to output the image to the browser instead of returning the image data through CGI:
imgdata = StringIO.StringIO()
fig.savefig(imgdata, format='png')
imgdata.seek(0)
#Something along these lines
print "Content-Type: img/png\n"
imgdata.seek(0)
print imgdata.read()
Once you are confident that an HTTP request to your Python script serves up a valid PNG, your front-end code only has to update the src
attribute of the image you are displaying:
function changeImage(imgName) {
var url = "http://localhost:8000/cgi-bin/dropdown.py?image=" + imgName;
var img = jQuery('#imgDisp');
img.src = url;
}
When your img
element is given a new src
value, the browser will automatically make a request to that URL and try to retrieve an image, which will load onto your page, replacing the previous image. You would have to modify your Python script, however, to expect a request parameter named image
, which holds a string. CGI has a simple method for accessing these parameter values passed inside the URL:
#Example CGI script
if __name__ == "__main__":
params = cgi.FieldStorage()
if "image" in params:
img = params['image']
#Generate the image and output it with the correct headers
else:
#Exception handling
print "Content-Type: text/html\n"
print """<html><body>No image name was specified!</body></html>"""
This page is a great resource that you can check out: http://lost-theory.org/python/dynamicimg.html
这篇关于使用javascript从python CGI返回图像的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!