1

关于移动端拍照上传图片的解决方案

场景

产品要求用户拍一张身份证和一张人像,然后后台php调用商用接口比对证件和人像的匹配度。图片描述

方案1:使用上传插件web-upload

  1. 证件和人像分别上传到后台,然后返回图片地址,前端回显。
  2. 点击核验按钮,ajax再将返回的图片地址传到后台,后台将地址转成bases64,调用接口比对,返回结果。

缺点

  1. 手机拍照图片过大,webupload压缩后,图片依然大,没上传一次花费时间过长,最后再调用接口比对时间花费也长。
  2. webupload的样式需要重新定义
.webuploader-pick {
        display: inline-block;
        width: 1.6rem;
        height: 1.6rem;
        position: absolute;
        left: 50%;
        top: 50%;
        -webkit-transform: translate(-50%, -50%);
        transform: translate(-50%, -50%);
        background-color: transparent;
    }
  1. webupload的input框没办法限制用户只能调用摄像头。(webupload加载完成后会生成一个input框,但是页面加载后不能重新给input添加属性,只有在上传中才能获取到).

方案2:使用原生的H5对象完成上传

  1. 用户点击input按钮,调用FileReader对象生成file.
  2. 利用canvas压缩图片,context进行绘图回显。
  3. 再将base64码dataURL转为file.
  4. 利用FormData对象追加file.发送后台。
  5. 后台$_FILES接受后,转为base64发送到接口,获取结果。

缺点

1.流程稍显复杂。
2.兼容性问题。
   // 扫描身份证
        $('.input-card').on('change', function () {
            var oFReader = new FileReader();
            var card_files = document.getElementById('card-file').files[0];
            oFReader.readAsDataURL(card_files);
            oFReader.onloadend = function (oFRevent) {
                img = new Image();
                img.src = oFRevent.target.result;
                img.onload = function () {
                    // 获取照片信息 等于6时照片会旋转90°
                    var photo = getPhotoOrientation(img);
                    // 压缩图片
                    var compress_data = compress(img);
                    // 将图片url转为file类型 (直接base64传到后台始终太大了)
                    card_img_file = dataURLtoFile(compress_data, 'img.png');
                    $(".crad-img").attr('src', img.src);
                    //$("#compress_card").attr('src', imgfile);
                }
                // 太大就进行压缩
            }
        })
        
        // 图片压缩
        function compress(img) {
            canvas.width = img.width
            canvas.height = img.height
            //利用canvas进行绘图
            context.drawImage(img, 0, 0); // 重要
            //将原来图片的质量压缩到原先的0.2倍。
            var data = canvas.toDataURL('image/jpeg', 0.1) //data url的形式
            return data
        }
          // base64 转file
        function dataURLtoFile(dataurl, filename) {
            var arr = dataurl.split(','),
                mime = arr[0].match(/:(.*?);/)[1],
                bstr = atob(arr[1]),
                n = bstr.length,
                u8arr = new Uint8Array(n);
            while (n--) {
                u8arr[n] = bstr.charCodeAt(n);
            }
            return new File([u8arr], filename, {
                type: mime
            });
        }
        //获取照片的元信息(拍摄方向)
        function getPhotoOrientation(img) {
            var orient;
            EXIF.getData(img, function () {
                orient = EXIF.getTag(this, 'Orientation');
            });
            return orient;
        }
         //确定核验
        $('#saveDate').on('click', function () {
            var _token = $('meta[name="csrf-token"]').attr('content');
            var formData = new FormData();
            formData.append("_token", _token); // 追加token
            formData.append("order_room_id", order_room_id); // 追加其他项目参数
            formData.append("face_img_file", face_img_file); // 追加文件
            formData.append("card_img_file", card_img_file);
            msg = layer.open({
                type: 2,
                content: '核验中'
            });
            $.ajax({
                url: '/check-in/ajax-real',
                type: 'post',
                data: formData,
                cache: false,
                processData: false, // 必填参数
                contentType: false, // 必填参数
                async: false,
                dataType: 'json',
                success: function (data) {
                    layer.close(msg);
                    if (data.status == 'success') {
                        layer.open({
                            content: data.msg,
                            skin: 'msg',
                            time: 2,
                            end: function (layero, index) {
                                // 跳转table页
                                window.location.href =
                                    "{{Route('check.table',['num'=>$total_num,'order_room_id'=>$order_room_id])}}";
                            }
                        });
                    } else {
                        layer.open({
                            content: data.msg,
                            skin: 'msg',
                            time: 3
                        });
                    }
                }

            });
        })

绿肥红瘦
0 声望1 粉丝