介绍
主要介绍Python实现的Http服务传输图片的2种方式:URL和字节流
以URL的方式传输图片
服务器端
基于tornado框架搭建简单的web服务, 提供post方法, 通过接收image_url字段获取图片的url,通过requests模块获取图片并进行后续的操作。图片的操作重点关注process()方法。
#!/usr/bin/python
# -*-coding=utf-8 -*-
import sys
import traceback
from StringIO import StringIO
import requests
import tornado
import tornado.ioloop
import tornado.web
from tornado.escape import json_encode
from PIL import Image
reload(sys)
sys.setdefaultencoding('utf8')
class Handler(tornado.web.RequestHandler):
def post(self):
result = {}
image_url = self.get_argument("image_url", default="")
print image_url
if not image_url:
result["msg"] = "no image url"
else:
result["msg"] = self.process(image_url)
self.write(json_encode(result))
def process(self, image_url):
"""
根据image_url获取图片进行处理
:param image_url: 图片url
"""
try:
response = requests.get(image_url)
if response.status_code == requests.codes.ok:
obj = Image.open(StringIO(response.content))
# TODO 根据obj进行相应的操作
return "ok"
else:
return "get image failed."
except Exception as e:
print traceback.format_exc()
return str(e)
class ImageServer(object):
def __init__(self, port):
self.port = port
def process(self):
app = tornado.web.Application([(r"/image?", Handler)], )
app.listen(self.port)
tornado.ioloop.IOLoop.current().start()
if __name__ == "__main__":
server_port = "6060"
server = ImageServer(server_port)
print "begin server"
server.process()
客户端
向服务器端的HTTP服务发送POST请求, 请求字段定义image_url。
#!/usr/bin/python
# -*-coding=utf-8 -*-
import json
import urllib
import urllib2
def post(server_url, params):
data = urllib.urlencode(params)
request = urllib2.Request(server_url, data)
return json.loads(urllib2.urlopen(request, timeout=10).read())
if __name__ == "__main__":
# 图片的URL
image_url = "/file/imgs/upload/202301/31/i0vh3us4jub.jpg"
# http服务的URL
url = "http://10.10.20.20:6060/image?"
print post(url, {"image_url": image_url})
以字节流方式传输图片
pickle模块和requests模块
服务器端
基于tornado的HTTP服务, 提供content参数,获取打包的图片内容,利用pickle.loads()方法获取图片内容,之后进行后续的操作。
HTTP搭建方式同URL方式, 简单修改post方法
# 其他部分参考上文URL服务的搭建方式
def post(self):
result = {}
content = self.get_argument("content", default=None)
if content is None:
result["msg"] = "no image content"
else:
result["msg"] = self.content_process(content)
self.write(json_encode(result))
def content_process(self, image_content):
"""
根据image_content进行相应操作
:param image_content: 图片内容
"""
try:
content = pickle.loads(image_content)
image = Image.open(StringIO(content))
print image
#TODO 根据image进行相应操作
return "ok"
except Exception as e:
print traceback.format_exc()
return str(e)
客户端
将本地图片文件利用pickle模块打包, 传送给服务器端进行处理; 利用requests模块获取远程图片并打包数据, 传送给服务器端进行处理。示例代码如下:
#!/usr/bin/python
# -*-coding=utf-8 -*-
import json
import urllib
import urllib2
import requests
import pickle
def post(server_url, params):
data = urllib.urlencode(params)
request = urllib2.Request(server_url, data)
return json.loads(urllib2.urlopen(request, timeout=10).read())
def remote_image(server_url, image_url):
"""
网络图片处理
:param server_url: 服务器端HTTP服务URL
:param image_url: 图片URL
"""
content = requests.get(image_url)
params = {"content": content}
print post(server_url, params)
def local_image(server_url, image_path):
"""
本地图片处理
:param server_url: 服务器端HTTP服务URL
:param image_path: 图片本地地址
"""
r_file = open(image_path, "rb")
content = pickle.dumps(r_file.read())
params = {"content": content}
print post(server_url, params)
if __name__ == "__main__":
url = "http://localhost:6060/image?"
# local image
file_path = "D:\\log\\fastText.PNG"
local_image(url, file_path)
# remote image
remote_url = "/file/imgs/upload/202301/31/i0vh3us4jub.jpg"
remote_image(url, remote_url)
详情参考:
http://www.tornadoweb.org/en/stable/
http://www.python-requests.org/en/master/