起因:webApp中需要一个拍摄照片并上传服务器的功能

由于我正好使用Hbuilder在做webApp,所以自然想到了使用h5+中的调用摄像头功能

从此开始了踩坑之旅。。。

1.手机连接电脑问题

       如果你没有连接问题请跳过。

手机通过数据线本来连接电脑好好的,突然就中断了,然后再咋也连不上电脑了,使用360手机助手连接也没用,而且我的手机设置和数据线及接口肯定没毛病,电脑重启一下就可以重连了,但总重启不是个事。

然后我就想到通过数据线真机调试有问题,我试试用无线wifi真机调试看看行不行,借鉴了这篇文章:

https://www.cnblogs.com/weibanggang/p/9961742.html

下载了WiFi ADB工具,还真给无线连上了,然后再赶紧真机调试,发现可以连接了。结果运行app时才发现有大坑,我html引入的jq,bootstrap,图片啥的资源都找不到,没办法,还是想办法用usb连接电脑吧。

查了半天,觉得唯一的可能就是我的usb驱动有问题,360手机助手提供的驱动可能兼容性不行,于是我下载了符合自己手机型号的usb驱动。因为我的是华为手机,只需要下载一个华为手机助手就可以了,下载地址:https://consumer.huawei.com/cn/support/hisuite/ 下载安装后连接手机就没问题了。(其他型号手机下载对应的驱动即可)

2.接口问题

由于官方文档写的不太清楚,理解有点费劲

5+调用相册接口官方文档:http://www.hcoder.net/tutorials/info_107.html

可知回调有三个参数:选择成功回调,选择失败回调,option配置参数。如果option配置了muitiple属性,则paths不再是一个路径,而是路径数组。

plus.gallery.pick(function(path){console.log(path);$("#albumCoverImg").attr("src",path);//给我的img元素添加src,可以直接显示出图片
});

返回的结果就是图片的物理路径

或者这么写:

plus.gallery.pick(function(paths){console.log(paths)plus.nativeUI.showWaiting();},function(e){mui.toast('取消了选择');},{multiple:true,maximum:5}
);

这样paths为一个数组,但貌似也只能选择一张图片,无法多选

调用摄像头接口:

plus.camera.getCamera().captureImage(function(e){console.log("e is" +  e);plus.io.resolveLocalFileSystemURL(e, function(entry) {var path = entry.toLocalURL();console.log(path);$("#albumCoverImg").attr("src",path) ; //upload(path);}, function(e) {mui.toast("读取拍照文件错误:" + e.message);});
});

3.上传问题

可以选择图片并返回图片的路径以后,上传图片又成了一个问题。

由于只能获取到图片的物理路径,js是无法只通过一个物理路径就上传这个文件的。因为浏览器的安全机制,所以得操作必须由用户点击来获取,只能使用h5中的input file才能获取到文件并保存到fileList中,且此数组为只读,外界获取不到,关于file可以看看这个https://blog.csdn.net/lianzhang861/article/details/80283120

所以这就不能直接将图片放在form中上传了,只能通过5+的上传模块上传

5+ uploader模块官方文档:http://www.hcoder.net/tutorials/info_108.html

原理应该就是通过http 的post请求上传文件

//服务端接口路径
var server = ip+"package/uploadImg";
// 上传文件
function upload(path){console.log(server)var wt=plus.nativeUI.showWaiting();var task=plus.uploader.createUpload(server,{method:"POST"},function(t,status){ //上传完成if(status==200){var data=JSON.parse(t.responseText);alert("上传成功:"+t.responseText);wt.close(); //关闭等待提示按钮}else{alert("上传失败:"+status);wt.close();//关闭等待提示按钮}}  );  //添加其他参数task.addData("name","test");task.addFile(path,{key:"file"});task.start();
} 

代码就是上述所写,server为上传的服务端接口,如果上传成功,则回调的status会返回200,不成功或者接口参数有问题会返回400或者500。t.responseText返回服务端返回的结果,一般服务端会返回json,解析一下json就可以使用了。

传输其他文件时如果还想添加其他参数,用.addData(key,value),添加图片用.addFile(图片路径,{key:后端接收文件的名字}),

配合后端代码看会好理解,后端我用java接收的:

后端代码

@RequestMapping(value = "/uploadImg", produces = "text/html;charset=utf-8")
@ResponseBody
public String uploadImg(@RequestParam Map<String, Object> paramMap,@RequestParam(value = "file") MultipartFile file,HttpServletRequest request) {Map<String, Object> map = new HashMap<>();String path=request.getSession().getServletContext().getRealPath("/")+"images\\";try {Map<String,String> name=uploadFile(path,file, request);map.put("success", true);map.put("code", "0");map.put("msg", "图片上传成功!");map.put("data","images/"+name.get("saveName"));} catch (Exception e) {e.printStackTrace();map.put("success", false);map.put("code", "-10");map.put("msg", "图片上传失败!");}return JSON.toJSONString(map);}public Map<String,String> uploadFile(String path,MultipartFile file, HttpServletRequest request) throws IOException {Map<String,String> result=new HashMap<String,String>();String fileName = file.getOriginalFilename();// String basePath=request.getSession().getServletContext().getRealPath("/");// path=basePath+path;            //设置文件保存路径
//        File tempFile = new File(path, new Date().getTime() + String.valueOf(fileName));String fileType = fileName.substring(fileName.lastIndexOf(".") + 1, fileName.length()).toLowerCase();String saveName=String.valueOf((new Date()).getTime()).substring(8)+(int)((Math.random()*999+1))+'.'+fileType;//File tempFile = new File(basePath+path, String.valueOf(saveName));File tempFile = new File(path, String.valueOf(saveName));if (!tempFile.getParentFile().exists()) {    //创建文件夹tempFile.getParentFile().mkdir();}if (!tempFile.exists()) {tempFile.createNewFile();}file.transferTo(tempFile);result.put("fileName",fileName);result.put("saveName",saveName);return result;
}

用标准的MultipartFile接收即可。

返回图片的保存路径,用来配合其他表单一起提交。

前端完整代码示例:

<!DOCTYPE HTML>
<html><head><title>情报制作</title><meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" /><link rel="stylesheet" href="../css/mui.min.css"> <link rel="stylesheet" href="../css/font-awesome-4.7.0/css/font-awesome.css" /><script src="../js/jquery-1.9.1.min.js" type="text/javascript" charset="utf-8"></script></head><body style="background-color: #f3f6f9;"><div style="height:500px;width:500px;overflow: hidden;"><img src="" alt="" id="albumCoverImg" style="width:100%;"/></div><button type="button" onclick="appendByGallery()">相册</button><button type="button" onclick="appendByCamera()">拍摄</button><script src="../js/mui.js"></script><script type="text/javascript">//扩展API完成后执行的操作function plusReady(){               //page.imgUp();} //弹出系统按钮选择框/*var page=null; page={ imgUp:function(){ var m=this; plus.nativeUI.actionSheet({cancel:"取消",buttons:[ {title:"拍照"}, {title:"从相册中选择"} ]}, function(e){//1 是拍照  2 从相册中选择 switch(e.index){ case 1:appendByCamera();break; case 2:appendByGallery();break; } }); } } */// 拍照添加文件function appendByCamera(){plus.camera.getCamera().captureImage(function(e){console.log("e is" +  e);plus.io.resolveLocalFileSystemURL(e, function(entry) {var path = entry.toLocalURL();$("#albumCoverImg").src = path;      $("#albumCoverImg").attr("src",path) ; upload(path);}, function(e) {mui.toast("读取拍照文件错误:" + e.message);});});   }// 从相册添加文件function appendByGallery(){plus.gallery.pick(function(path){console.log(path);$("#albumCoverImg").attr("src",path) ;  upload(path); });} //服务端接口路径var server ='http://192.168.100.149:8085/packagePK/package/uploadImg';// 上传文件function upload(path){console.log(server)var wt=plus.nativeUI.showWaiting();var task=plus.uploader.createUpload(server,{method:"POST"},function(t,status){ //上传完成if(status==200){var data=JSON.parse(t.responseText);console.log(data.data);alert("上传成功:"+t.responseText);wt.close(); //关闭等待提示按钮}else{alert("上传失败:"+status);wt.close();//关闭等待提示按钮}}  );  //添加其他参数task.addData("name","test");task.addFile(path,{key:"file"});task.start();} //扩展API是否准备好,如果没有准备好则监听plusReady if(window.plus){plusReady();}else{document.addEventListener("plusready",plusReady,false);}</script></body>
</html>

探索HTML5 Plus 拍照或者相册选择图片上传过程相关推荐

  1. MUI 拍照和从系统相册选择图片上传

    要完成用MUI 拍照和从系统相册选择图片上传的功能,可以理解成有三个功能 1 调用手机相机的功能(可以查看官方API  http://www.html5plus.org/doc/zh_cn/camer ...

  2. MUI+HTML5+Plus 拍照或者相册选择图片并上传服务器

    引入文件 css:mui.min.css.app.css.iconfont.css.feedback-page.css.font-awesome.min.css js:jquery.js.common ...

  3. android拍照所需的权限,eclipse --- Android拍照,相册选择图片以及Android6.0权限管理...

    [实例简介] eclipse --- Android拍照,相册选择图片以及Android6.0权限管理 [实例截图] [核心代码] camreainandroidm └── camreainandro ...

  4. iOS学习:调用相机,选择图片上传,带预览功能

    iOS学习:调用相机,选择图片上传,带预览功能 发表于2年前(2013-05-30 21:38)   阅读( 18194) | 评论( 16) 27人收藏此文章,我要收藏 赞3 8月22日珠海 OSC ...

  5. h5 php 拍照上传图片,H5拍照、选择图片上传组件核心

    背景 前段时间项目重构,改成SSR的项目,但之前用的图片选择上传组件不支持SSR(server-side-render).遂进行了调研,发现很多的工具.但有的太大,有的使用麻烦,有的不满足使用需求.决 ...

  6. H5拍照、选择图片上传组件核心

    背景 前段时间项目重构,改成SSR的项目,但之前用的图片选择上传组件不支持SSR(server-side-render).遂进行了调研,发现很多的工具.但有的太大,有的使用麻烦,有的不满足使用需求.决 ...

  7. 安卓开发小米4,酷派 手机适配和调用系统相机相册做图片上传的问题

    // 启动相机startCamera.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {/ ...

  8. php 点击选择图片上传,微信小程序图片选择、上传到服务器、预览(PHP)实现实例...

    微信小程序图片选择.上传到服务器.预览(PHP)实现实例 小程序实现选择图片.预览图片.上传到开发者服务器上 后台使用的tp3.2 图片上传 请求时候的header参考时可以去掉(个人后台验证权限使用 ...

  9. 在线相册 ,图片上传, 基于 Spring boot vuejs element ui mysql 的项目

    最近想学关于vuejs 和 element ui ,趁着工作之余开发了一个在线相册的项目,功能有 注册,登录,预览,各种中心,图片上传,我的资源,图片编辑等,,在此做一个分享吧. Git 地址 :ht ...

最新文章

  1. SQL Server Profiler工具
  2. 化工原理知识点总结复习重点
  3. UIApplication,UIWindow,UIViewController,UIView(layer)
  4. 你了解 Assembly.Load 吗?
  5. 深度思考|TCP协议存在那些缺陷?
  6. win10使用docker desktop安装k8s一直starting解决方法
  7. Node.js 应用故障排查手册 —— 正确打开 Chrome devtools
  8. HDU1251 统计难题 trie树
  9. java pdf替换文字_java 查找替换pdf中的指定文本
  10. iis提示“另一个程序正在使用此文件,进程无法访问。(异常来自HRESULT:0x80070020) ”解决办法
  11. 智能三路CAN总线路由器集线器助力灵活组网
  12. python游戏制作rpg_2. Molten从零开始做独立游戏-引擎选用
  13. python3 yield from用法
  14. 黑龙江大米:正宗东北大米,源于黑土地
  15. 像踢球一样玩转Redux和React
  16. vue+vue-ueditor-wrap+秀米
  17. surface和华为平板_微软的Surface Duo是手机和平板电脑的完美融合
  18. Qt qlabel怎样实现透明
  19. mysql inner join 链接三个或多个表
  20. 冰箱的矢量变频技术是什么

热门文章

  1. 小米note3android beam,宝联beamlink安卓版手机连接说明.pdf
  2. 词向量:对word2vec的理解
  3. 第20课 Altium Designer20(AD20)+VESC6.4实战教程:更改Type-C封装 (北冥有鱼)
  4. 常见编码和编码头BOM
  5. Microsoft.NET Framework 4.5.5 官方中文版
  6. 【干货分享】流程DEMO-付款申请单
  7. php企业微信付款到零钱,企业付款到零钱功能介绍及常见问题
  8. 重庆师范大学计算机科学与技术宿舍,重庆师范大学宿舍条件及图片
  9. linux midi端口,在Linux下使用MIDI软波表
  10. 如何在线将CAD转成PDF格式