吐个槽:网上找出来的,大部分是网页截图并下载到browser(客户端),保存到服务的,能用的,实在是太少了。以至于我这种新手,难受。
场景说明:我这边要写个小程序:用户填写一些数据参数,提交到后台,进行分析处理,处理的结果以图片的方式反馈到用户手机界面。记录用户提交的数据的同时,要求能够将反馈的图片一并存入数据库,方便用户分享。
环境:Windows 环境下安装xampp,使用的laravel框架。
功能实现思路:
step1:处理后的数据,生成想要的网页
step2:用html2canvas截取指定部分网页为canvas数据
step3:将canvas数据通过ajax传递给PHP
step4 : PHP接收数据,保存为图片,存在服务器上
需要准备的文件:
html2canvas.min.js
jquery.min.js
在<head>
引入两个文件
<script src="//cdn.bootcss.com/jquery/1.11.3/jquery.min.js" ></script> //用CDN引入
<script type="text/javascript" src="/js/html2canvas.min.js"></script> //本地引入
源码说明
以下代码是放在view文件里面的,写在用同一个文件即可。对了,这个文件必须引入上述的两个js文件。
<div class="main-picture">
这里面就是你要保存为图片的内容
</div>
<script type="text/javascript">
html2canvas(document.querySelector(".main-picture"),{
useCORS:false,//设置可以素材可以跨域,移动端不兼容
allowTaint: false,//默认就是false,允许跨域
taintTest: true,//默认就是false,是否在渲染前测试图片
scale:window.devicePixelRatio,//解决清晰度的问题可以改变scale的值
}).then(canvas => {
var dataUrl = canvas.toDataURL();
var newImg = document.createElement("img");
newImg.src = dataUrl;
//canvas.setAttribute('id','thecanvas');
//document.body.appendChild(newImg);如果只需要显示,不需要保存,这句代码可以直接在body内显示截取内容;
saveimg(dataUrl)
});
// 保存图片
function saveimg(img){
var mydate = (new Date()).valueOf();
$.ajax({
url:"{{ url('/user/saveImage') }}",
type:'post',
dataType:'json',
data:{img:img,
mydate:mydate},
success:function(data){
if (data.status) { //此部分函数在于提示是否成功,可以忽略。
//toast.success(data.info,'温馨提示');
//window.location.href="//uploads//screen//".mydate.".png";
setTimeout(function(){
//alert('成功');
}, 1000)
}else{
//toast.error(data.info,'温馨提示');
setTimeout(function(){
//window.location.reload(true);
//alert('失败');
},1200)
};
}
});
alert('温馨提示:长按即可分享!'); //服务器生保存图片需要时间,立即载入会报错,用alert的方式,增加延迟,经过测试,比setTimeout更实用。
//setTimeout("fun()",2000);
window.location.href="/Uploads/Screen/"+mydate+".png"
}
</script>
上述代码将图片的内容、命名通过 ajax 方法POST到了test.com/user/saveImage。所以接下来的代码,就是接收并存储图片
public function saveImage(Request $request)
{
$pictureFlow = $request->img;
$NOW_TIME=$request->mydate;
// 这里是用了框架,如果没用框架,直接用$_POST['img'],$_POST['mydate']即可
$pictureFlow = str_replace('data:image/png;base64,', '', $pictureFlow);
$pictureFlow = base64_decode($pictureFlow);
$new_pic_path = public_path().'/Uploads/Screen/'.$NOW_TIME.'.png';
$ret = file_put_contents($new_pic_path, $pictureFlow);
}
基本思路是这样了,laravel中这个代码还需要做一步,就是解决csrfToken的问题。两个办法,第一种就是在ajax位置加入相应的token,这个方法比较严谨。
$.ajaxSetup({
headers: { 'X-CSRF-TOKEN' : '{{ csrf_token() }}' }
});
//在$.ajax 前面先加入token,如上方代码
$.ajax({
url:"{{ url('/user/szd/saveImage') }}",
第二个办法就是,在VerifyCsrfToken里面,加一句except(加token报错的,只能用这个咯):
protected $except = [
'/user/saveImage'
];
有任何疑问,欢迎留言。看到必回。