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

起因: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>

 

 

 

 

  • 0
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

豆趣编程

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值