html5调用手机相机并压缩、上传

前端js实现图片上传的原理是通过input标签的type=file属性将input标签定义为上传文件,对input进行onchange事件的监听,当input的value值改变时代表用户已经上传了图片,而input的value值就是用户上传的图片的相对路径,new一个FileReader对象,将图片转换成base64格式的编码,动态创建img标签并将转换后的编码赋值给img标签的src属性即可。

h5页面使用原生JS实现图片上传预览功能

<ul class="weui-uploader__files" id="uploaderFiles">
    <li class="weui-uploader__file">
        <img src="/statics/front/images/picture02.jpg"/>
        <input type="hidden" name="files[]" value="/statics/front/images/picture02.jp"/>
        <i class="weui-icon-cancel"></i>
    </li>
</ul>
<div class="weui-uploader__input-box">
    <input id="uploaderInput" class="weui-uploader__input" type="file" accept="image/*" multiple="">
    <img style="margin-top: 10px;" src="/statics/front/images/camera.png" width="45%" alt="">
    <p>添加图片</p>
</div>

图片压缩处理:

  1. 因为要做的是手机拍照上传,现在的手机拍照片都很大,如果原图上传,太消耗用户流量,于是要解决图片压缩的问题。
  2. 通过change事件,监听图片上传,通过readerAsDataURL获取上传的图片。
  3. 对上传的图片进行压缩,需要借助于canvas API,调用其中的canvas.toDataURL(type, encoderOptions); 将图片按照一定的压缩比进行压缩,得到base64编码。
function showFileImg($this, file) {
    var maxSize = 2 * 1024 * 1024//2M
    if (file.size > maxSize) {
        alert('您上传的文件' + file.name + '不许大于2M')
        return
    }

    //将图片对象转换成base64位格式字符串
    (function (file) {
//            var reader = new FileReader()
//            reader.readAsDataURL(file)
//            reader.onload = function (e) {
//                var post_base64image_str = this.result
//
//                var imgUrl = window.URL.createObjectURL(file)
//                //获取点击的文本框
//                var files = $this.parents('.weui-uploader').find('.weui-uploader__files')
//                var html = '<li class="weui-uploader__file" style="background-image: url(' + imgUrl + ')">\n' +
//                    ' <img src="' + imgUrl + '"/><input type="hidden" name="files[]" value="' + post_base64image_str + '"/>\n' +
//                    '  <i class="weui-icon-cancel"></i>\n' +
//                    ' </li>'
//                files.append(html)
//            }

        var formFile = new FormData();
        formFile.append("file", file);//添加参数
        var data = formFile;
        $.ajax({
            url: "/bbs/index/upload",
            data: data,
            type: "Post",
            dataType: "json",
            cache: false,//上传文件无需缓存
            processData: false,//用于对data参数进行序列化处理 这里必须false
            contentType: false, //必须
            success: function (result) {
                var imgUrl = result.src;
                //获取点击的文本框
                var files = $this.parents('.weui-uploader').find('.weui-uploader__files');
                var html = '<li class="weui-uploader__file">\n' +
                    ' <img src="' + imgUrl + '" alt="' + file.name + '"/>\n' +
                    '<input type="hidden" name="files[]" value="' + imgUrl + '"/>\n' +
                    '  <i class="weui-icon-cancel"></i>\n' +
                    ' </li>'
                files.append(html);
            }
        })

    })(file)
}

//图片上传
$('#uploaderInput').on('change', function (e) {
    var $this = $(this)
    //图片对象
    var files = $this.get(0).files
    for (var i = 0; i < files.length; i++) {
        var file = files[i]
        showFileImg($this, file);
    }
    $this.val(''); //解决同一个图片不能上传bug,同一个图片不能触发change  
})
//点击叉叉 删除图片
$(document).on('click','.weui-uploader__files .weui-icon-cancel',function () {
    $(this).parents('.weui-uploader__file').remove()
})

等比缩放图片

function drawOnCanvas(file) {
    var reader = new FileReader();
    reader.onload = function (e) {
        var dataURL = e.target.result,
            canvas = document.querySelector('canvas'),
            ctx = canvas.getContext('2d'),
            img = new Image();
        img.onload = function () {
            var square = 320;
            canvas.width = square;
            canvas.height = square;
            var context = canvas.getContext('2d');
            context.clearRect(0, 0, square, square);
            var imageWidth;
            var imageHeight;
            var offsetX = 0;
            var offsetY = 0;
            if (this.width > this.height) {
                imageWidth = Math.round(square * this.width / this.height);
                imageHeight = square;
                offsetX = -Math.round((imageWidth - square) / 2);
            } else {
                imageHeight = Math.round(square * this.height / this.width);
                imageWidth = square;
                offsetY = -Math.round((imageHeight - square) / 2);
            }
            context.drawImage(this, offsetX, offsetY, imageWidth, imageHeight);
            var base64 = canvas.toDataURL('image/jpeg', 0.5);
            $('#j_thumb').val(base64.substr(22));
        };
        img.src = dataURL;
    };
    reader.readAsDataURL(file);
}

PHP后端将base64图片转成图片文件

/**
 * [将Base64图片转换为本地图片并保存]
 * @param  [Base64] $base64_image_content [要保存的Base64]
 * @param  [目录] $path [要保存的路径]
 */
function base64_image_content($base64_image_content, $path) {
    //匹配出图片的格式
    if (preg_match('/^(data:\s*image\/(\w+);base64,)/', $base64_image_content, $result)) {
        $type = $result[2]; //图片后缀
        if ($type === 'jpeg') {
            $type = 'jpg';
        }
        $new_file = $path . "/" . date('Ymd', time()) . "/";
        if (!file_exists($new_file)) {
            //检查是否有该文件夹,如果没有就创建,并给予最高权限
            mkdir($new_file, 0700);
        }
        $new_file = $new_file . md5($base64_image_content) . ".{$type}";
        if (file_put_contents($new_file, base64_decode(str_replace($result[1], '', $base64_image_content)))) {
            return ltrim($new_file, ".");
        } else {
            return false;
        }
    } else {
        return false;
    }
}

效果截图
html5调用手机相机并压缩、上传


相关推荐