实现小程序接收django的图片并部署到windows服务器上
继上一篇:用pycharm搭建django框架接收微信小程序的图片后续
链接: https://blog.csdn.net/qq_44933075/article/details/108031948.
七、django图片渲染到小程序页面
思路是通过cv2把小程序传过来的图片进行base64编码,因为网络请求支持base64码,所以返回给小程序的时候,小程序用imgdat来接收base64码进行背景渲染
7.1django将图片进行base64转码
因为要返回图片思路是用base64编码进行传输和解码
参考了别人的方法来验证一下
链接: https://blog.csdn.net/loovelj/article/details/92833070
.
在pycharm中新建了一个实例,用cv2和矩阵的方法都进行了实验,编码都成功了
并且打印下来的两种转换的结果,发现两种编码方式不一样,所用用网上的在线base64转换工具直接粘贴上去发现,
在线base64转码链接: http://tool.chinaz.com/tools/imgtobase/.
均无法转为图片,
开始考虑问题出在哪里,于是我在转码网站进行手动传图,把获取的base64代码复制到表格里,再把程序用矩阵的转码的base64复制到表格查看代码,代码一模一样
发现头文件不一样,把原来的头
进行删除,这个b‘其实我转码时候的自定义的数据流名字(bb)于是我把头改成这个
data:image/jpg;base64,#注意有逗号
再转换,加了头文件还是无法转换成功,
![在这里插入图片描述](https://img-blog.csdnimg.cn/20200818232115546.png?x-oss-process=image/watermark,type_ZmFuZ3p
于是我通过表格对比发现,末尾多了一个 ’ 符号删掉它,果然图片就转化好了
同理cv2只用加 data:image/jpg;base64 不用改后缀就可以读取了
总结一下 用第一种cv2方法比第二种矩阵方法更好,cv2不会把转换图片的数据流名字加上,并且长度比较短,这样传输更快
我们把base64转码加到django里,
img_base64 = cv2.imread(path+open_id+'.jpg') # 要被base转换的图片地址
receive_base = base64.b64encode(cv2.imencode('.jpg', img_base64)[1]).decode() # 把转码后的值给receive_base
print(receive_base)
运行的出现这种情况,
这是因为我函数里有一个if判断它是否存在,如果第二上传就会出现没有办法写入的报错果断删除,这是参照我小伙伴的程序进行调试的,他的链接
链接: https://blog.csdn.net/weixin_43951163/article/details/108109351.
删掉if判断后之后又出现这个报错
这个的意思是cv2没有进行转码没成功,所以是路径问题查了大半天发现这句话少了一个path加上后就可以了
最后运行一下,打印出图片的base64码了
最后用最关键的语句
return HttpResponse(receive_base) #返回base64码
完整的django代码如下
def get_image(request):
if request.method == "POST": #判断网络请求是否为POST请求
image=request.FILES['image'] #判断请求的名字为image
print(image)
open_id=request.POST.get('openid') #接收网络请求过来opid
basedir= os.path.dirname(__file__) #获取当前路径的上一级 即回到APP1目录
path=basedir+'/static/image/' #进行地址的拼接
with open(path+open_id+'.jpg','wb')as f: #转为二进制写入
f.write(image.read()) #文件写入流
f.closed #文件关闭写入流
# return HttpResponse('上传成功') # 返回上传成功
img_base64 = cv2.imread(path+open_id+'.jpg') # 要被base转换的图片地址
receive_base = base64.b64encode(cv2.imencode('.jpg', img_base64)[1]).decode() # 把转码后的值给receive_base
print(receive_base)
return HttpResponse(receive_base)
7.2django将base64码返给小程序做预览图片
小程序端js,这一部分是接收base64码,并把它进行去回车操作再渲染放在imgData变量里
完整的代码
chooseImage: function (e) {
var that = this;
wx.chooseImage({
count: 1,
sizeType: ['original', 'compressed'], // 可以指定是原图还是压缩图,默认二者都有
sourceType: ['album', 'camera'], // 可以指定来源是相册还是相机,默认二者都有
success: function (res) {
// 返回选定照片的本地文件路径列表,tempFilePath可以作为img标签的src属性显示图片
const tempFilePaths=res.tempFilePaths
console.log(tempFilePaths)
console.log(that.data.openid)
wx.uploadFile({ //上传图片到django框架
filePath:tempFilePaths[0],
name: 'image',
url: 'http://127.0.0.1:8000/get_image', //路由地址
method:'POST', //路由操纵类型
header:{ //头文件
'content-type':'application/x-www-form-urlencoded' //发送过去的编码属性
},
formData:{ //附加属性opid
openid:that.data.openid,
},
success: res => { // 上传django成功时的回调函数
console.log('[上传文件] 成功:', res)
wx.showToast({
title: '上传成功',
icon:'success'
})
console.log(res.data) //打印返回的值
var base64Img = res.data
var imgData = base64Img.replace(/[\r\n]/g, '') //将回车换行换成空字符
that.setData({
imgData: imgData
})
},
fail: e => { // 调用失败时的回调函数
console.error('[上传文件] 失败:', e);
wx.showToast({ // 显示消息提示框
icon: 'none',
title: '上传失败',
})
},
complete: () => { // 调用完成时的回调函数
wx.hideLoading() // 隐藏加载提示框
}
})
that.setData({
files: that.data.files.concat(res.tempFilePaths)
});
if (that.data.hidden='flase'){
console.log(that.data.hidden)
that.setData({
hidden:true
})
}
}
})
},
wxml端,我们之前测验过,cv2转过来的是没有头文件data:image/png;base64,所以在想预览的image里就直接用前缀再加上{{imgData}} 这样就可以正常显示了
当我们点击完上传之后,预览的图片框就会返回我们需要的base64的背景
八、将base4码保存为本地图片
第一步、这里我们用wx.getFileSystemManager();文件管理器来把base64保存为缓存图片。
第二步、用wx.saveImageToPhotosAlbum()保存图片,这个api是保存网络图片的函数,如果使用时无效时用wx.saveFile()来保存。
第三步、最后为了程序的鲁棒性我们最后调用获取图片的授权
8.1小程序把base64转码成图片
showTopTips:function(e){
let code =this.data.imgData; // 后台返回的base64图片,没有带data:image/png;base64,的前缀。
let src = `data:image/jpg;base64,${code}`;
const fsm = wx.getFileSystemManager(); // 获取文件管理器
code = code .replace(/\ +/g, ""); //去掉空格方法
code = code .replace(/[\r\n]/g, "");//去掉回车
const buffer = wx.base64ToArrayBuffer(code ); // 将 base64 字符串转成 ArrayBuffer 对象
const fileName = wx.env.USER_DATA_PATH + '/share_img.jpg'; // 文件系统中的用户目录路径 (本地路径)
/**
* @param fileName: 文件路径
* @param buffer : 要写入的文本或二进制数据
* @param binary: 指定写入文件的字符编码
*/
fsm.writeFileSync(fileName, buffer, 'binary'); // 写入文件, 同步方法
console.log(fileName); // 写入成功后就可以访问到该图片路径了
})
}
8.2将图片保存在本地
这里我们用 wx.saveImageToPhotosAlbum来保存网络图片
wx.saveImageToPhotosAlbum({
filePath: fileName,
success (res) {
wx.showToast({
title: '保存成功',
icon: 'success',
duration: 2000
})
},
8.3授权访问图片权限
当保存图片失败的时候我们调用获取图片权限的api
fail:function(result){
if (!res.authSetting['scope.writePhotosAlbum']){
//未授权访问本地相册,引导用户前往设置
wx.showModal({
title: '温馨提示',
content: '用户拒绝授权访问本地相册将导致头像无法保存!如需继续操作,请点击确定前往开启授权。',
success: function (res) {
if (res.confirm) {//点击确定后前往授权设置页面
wx.openSetting()
}
}
})
}
}
当我们点击下载图片的时候就会弹出,让我们保存的路径,如果是手机则会直接保存。
九、小程序端功能完善
因为我们的流程是小程端发送请求并且带上参数给django,参数包括opid标识 imgsieze图片尺寸 imgcolor图片颜色 ,所以要进行功能完善,传值的方法是放在formData里,并且给他设置一个名字,这样django也可以实现了
9.1完善颜色和尺寸参数的传值
如图,发现这六个按钮
对应的六个值,进行程序判断时候使用id进行判断的,我们只需要找到对应的位置id的name拿出来就好了
颜色的在这里,这是一个判断语句,我们只需在判断语句成功后,加上 this.data.imgsize=this.data.buttons[i].name赋值给我们自己创建的imgcolor就可以了,如下:
尺寸的在这里,同理创建一个imgsize接收
this.data.imgsize=this.data.buttons[i].name
这里大家注意一下 this和that的区别,一般函数比较多的时候会在最大的函数上加一个var that=this,在chooseimage函数里调用全局变量或者赋值都用this.setdata().this.data.***, 但是如果进了wx.chooseImage里是检测不到全局的this,所以会向上一层找,发现this变成了that,再用that进行全局的取值,以及that.setdate等操作
最后我们把全局变量放到网络请求里
因为formData是请求子函数里的,所以调用全局的值时就要用到that,用this就会报错
9.2用缓存技术来实现不同页面传递opid
由于授权页在login.wxml里上传在grid_demo.wxml里,所以在小程序授权页面login.wxml的云函数wx.cloud.callFunctiom()里调用成功的时候用
wx.setStorageSync('opid', res.result.openid) //把opid给本地缓存
把opid保存到本地,需要这部分代码的可以看到我第一篇文章
《微信云开发实现每个用户在云端上传并且下载自己对应的图片》里面都有详细的代码和注释
链接: https://blog.csdn.net/qq_44933075/article/details/107735724.
在grid_demo.wxml的onload函数里加上,
this.data.openid=wx.getStorageSync('opid')
这个是获取缓存的函数,只用指出缓存的名字,就会获取对应的值,顺便再打印出来康康
这样子只要用户授权过就会在grid_demo.wxml有缓存我们就可以用opid啦
另外我们也要在django的views里进行接收,接收的名字就和小程序端fromData里的名字一一对应
当小程序上传图片的时候,我们的控制台就会打印出用户请求的值
这样流程就算完成啦,参数传过来了就等待后方的处理
十、部署windows服务器
框架完善之后,我们就要部署服务器了,这次我们搭建的是windows服务器,主要用的环境是python3.5+apache2.4 VC14+mod_wsgi,个人不推荐windows进行搭建django,原因如下
1、因为windows版本的服务器兼容性很不好,因为很少人用,所以资料和库也很少,能用的服务环境都是几年前的版本
2、容易被攻击(因为大多数病毒都是windows的),安全性系数差
3、同等配置下,服务器的性能要比其他系统卡,唯一的好处就是图像化操作
想看centenos服务器搭建的可以看我小伙伴的
链接: https://blog.csdn.net/weixin_43951163/article/details/108109351.
如果你还想windows服务器的话,那最后确认一件事情,!!!!!!!!看mod_wsgi官网的版本是否支持自己的版本apache和python,不然搭建到最后也要重来,如果程序一定要python3.6及以上版本的功能,就另寻它路。
mod_wsgi链接: http://www.lfd.uci.edu/~gohlke/pythonlibs/#mod_wsgi.
注意不要选没有apache的因为djiango要放在apache上,目前官网最高也才python3.5我选的是
mod_wsgi-4.5.24+ap24vc14-cp35-cp35m-win_amd64.whl
我就以这个标准搭建
10.1配置iis服务
详细可以看看
链接: https://www.cnblogs.com/djangocn/p/10227006.html
10.2配置python和django,
注意所有的东西尽量从官网下,如果从网上下,会出现不知名的错误
进入windows服务器,国外的网址,用服务器访问会比本机快一点,所有下载可以在服务器上操作
经过了几天的测试,为了大家方便 我就直接把一组匹配的包上传百度云给大家使用
链接: https://pan.baidu.com/s/1XUGrKN2nPn-fsYdGe3jnTQ.
密码:chao
把解压的目录放在我们的服务器电脑里随便一个位置,但自己要记住
一、安装python
二、安装django和配置djiango
详细的步骤可以看我上一篇文章
链接: lhttps://blog.csdn.net/qq_44933075/article/details/108031948.
在基础上加上
cd 到django的项目 我的是C:\xmprogram\ZJZ
pip freeze > requirements.txt,这时候根目录就会出现一个requirements.txt的配置文件
再次执行 pip install -r requirements.txt 把配置信息写进去,这时候,我们打开requirements.txt里面就有我们的配置文件了
10.3安装apche服务
先安装解释器,两个都要
成功后
打开我们的apache24 vc14(官网里没有的,这是实验多个版本发现这个版本可以的)
直接解压文件会出现三个文件
我们打开apche24
我的路径是C:\seting\apache\Apache24\conf 下有一个httod.conf配置文件,我们修改一下参数
在httpd.conf里加搜索ServerName 把这句的#去掉,改成如图这样
然后打开命令提示符
cd到C:\seting\apache\Apache24\bin就是apche的bin目录下
httpd -t
检测配置是否正确
再用httpd -k install -n Apache来安装到windows
httpd -k install -n Apache
最后我们来到bin文件夹点击ApacheMonitor.exe来启动服务
点击start启动一下,我们的服务就启动好了
10.4安装mod_wsgi并配置
直接输入
pip install "C:\seting\mod_wsgi\mod_wsgi-4.5.24+ap24vc14-cp35-cp35m-win_amd64.whl
来安装
输入 mod_wsgi-express module-config来获取mod——wsgi的配置
如果出现的配置信息只出现两条没有loadfile:*******,那就不要在虚拟环境下安装,这样apache和mod—wsgi无法链接,最后打开C:\seting\apache\Apache24\conf下的httpd.conf
配置文件在末尾加上以下代码,
LoadFile "c:/python/python35.dll"
LoadModule wsgi_module "c:/python/lib/site-packages/mod_wsgi/server/mod_wsgi.cp35-win_amd64.pyd"
WSGIPythonHome "c:/python"
#Django项目的路径,注意是项目的根目录:
WSGIPythonPath C:/xmprogram/ZJZ
#Django项目中wsgi.py的路径:
WSGIScriptAlias / C:/xmprogram/ZJZ/ZJZ/wsgi.py
#配置wsgi.py的访问权限
<Directory C:/xmprogram/ZJZ/ZJZ>
AllowOverride None
Options None
Require all granted
</Directory>
#配置django静态文件static的位置和权限
Alias /static "C:/xmprogram/ZJZ/indexapp/static"
<Directory C:/xmprogram/ZJZ/indexapp/static>
AllowOverride None
Options None
Require all granted
</Directory>
#强制用python解释器解析识别不了库
WSGIApplicationGroup %{GLOBAL}
前三句话就是我们上面获取的mod-wsgi的配置,路径对应自己的Django改
然后我们用httpd -t 测试一下
另外我们django也需要修改django程序里seting文件的
DEBUG=false
ALLOWED_HOSTS = ['*'] #任意网络访问
如果启动还是错误的话
就去看apache下logs文件夹里面错误日志,对着日志慢慢改,我是改了很久的,才把正确的方法做给大家看,中间的学校过程很艰辛,我记录了很多报错的解决方案 ,详细可以看
链接: https://blog.csdn.net/qq_44933075/article/details/108668281
.
最后启动服务
这样三个服务就连接上了
最后我们在浏览器上输入 localhost:8080或www.chaochaotool.top:8080,就显示出我们django的页面了,其中8080为我们httpd.conf里设置的端口号码
在浏览器输入localhost:8080或www.chaochaotool.top:8080就会出现django的页面,地址就是我们在httpd.conf里设置的ServerName