关键词:python、前后端分离、url返回图片
现在前后端分离的情况,比较常见,我一个Django框架后端,要为安卓、IOS、小程序、网站、手机H5网页等好多地方提供接口。
有个需求是这样的:把数据库里面的一个对象,按照一定的格式生成图片或者pdf。
我的思路如下:
1、生成Django模板网页;
2、该网页转图片;
第一步就是咱们的本职,不多描述了,主要看看第二步如何实现。
在网上找了好多的工具之类的东西,最终选择的是wkhtmltox,因为他适应多平台
链接:点击这里跳转去下载软件的页面
适应的系统:
Downloads选择右边的,都是64位就行,相信没人用32位的了。
我的电脑是deepin系统(Debian的儿子,Ubuntu的弟弟)版本15.6,公司服务器是CentOS 7,一切安装使用均正常。
我的deepin用户界面挺友好的,下载下来.deb包,傻瓜式安装;
服务器的CentOS,下载的.rpm包,需要使用rpm命令安装,不会的百度一下,也是秒安,另外CentOS需要安装一个汉字字体(不会的,百度“centos 安装 字体”,不用安装太多,安装一两个就够了,例如这个博客的安装字体教程,写的不错,很详细),(我安装的字体是simsun.ttf和simhei.ttf,百度之后下载的),否则url转存为图片时,汉字没办法正确显示。
# 简单使用
# 命令名称 url 图片名字
wkhtmltoimage www.bing.com bing.png
# 查询命令
rpm -qal | grep wkhtmltox
ls -lha | grep wkh
# 查找命令路径
which wkhtmltoimage
which wkhtmltopdf
# 创建软连接
sudo ln -s /usr/local/bin/wkhtmltoimage /usr/bin/wkhtmltoimage
sudo ln -s /usr/local/bin/wkhtmltopdf /usr/bin/wkhtmltopdf
然后就可以使用方便的python,调用系统终端命令,将url转换为图片:
class get_img_from_url():
def __init__(self,req_url,file_name):
# 图片保存路径拼接
self.save_path = local_settings.MEDIA_ROOT + "/url_trans_img/"
file_name += ".png"
self.save_path += file_name
# python调用终端命令
import subprocess
self.handle_result = subprocess.getstatusoutput("wkhtmltoimage {} {}".format(req_url, self.save_path))
# print(a)
# (0, '运行结果字符串')
self.img_url = local_settings.MEDIA_URL + "url_trans_img/" + file_name
# print(a[-1].split())
# print(a[-1].split()[-1])
# 最后一行是“Done”,表示成功了
self.msg = self.handle_result[-1]
if self.handle_result[-1].split()[-1] == "Done":
self.result_x = True
else:
self.result_x = False
然后就可以在views.py视图类里面,调用这个方法了:
# 继承的视图类,这个你随便放一个合适的视图类就行
class GetImgFromUrl(AllowAnyView):
"""
传url获取图片
"""
# 这个是swagger的代码,可以不用
schema = AutoSchema(
manual_fields=[
coreapi.Field(
"req_url",
location="query",
required=True,
description="需要获取图片的url",
),
]
)
# get方法
def get(self, request):
# 参数接收
req_url = request.query_params.get("req_url", "")
# 文件名生成
import random
num = random.randint(10000,99999)
timestamp = time.time()
file_name = str(num) + "_" + str(timestamp)
# 方法调用
result_obj = get_img_from_url(req_url, file_name)
# 结果判断
if result_obj.result_x: # 如果成功了,图片的url返回给前端
return success(dict(save_path=result_obj.save_path,
msg=result_obj.msg,
img_url=result_obj.img_url,
))
else: # 如果失败了
return fail(1,result_obj.msg) # 这是一个自定义的 错误时返回的 响应 对象
urls.py
url(r'^get_img_from_url$', views.GetImgFromUrl.as_view()),
# 传url获取图片
然后大功告成!
别忘了写个定时任务crontab,定时删除一下保存的图片,删除你保存的那个路径下、以.png结尾的文件就行(不会的自行百度)。