zoukankan      html  css  js  c++  java
  • html5调用手机相机并压缩、上传

    使用input file[camera]属性调用相机

    简直So easy!

    <input type="file" accept="image/*;" capture="camera" >

    只需要这么一条简单的代码,在手机浏览器点击就可以打开相机了。

    capture是什么?其实就是对打开方式的设置。

    <!-- capture=camcorder,调用手机摄像功能 -->
    <input type="file" accept="video/*" capture="camcorder" >
    <!-- capture=microphone,调用手机录音功能 -->
    <input type="file" accept="audio/*" capture="microphone" >

    魅族MX5测试结果:

    • 谷歌浏览器可以打开相机和摄像功能,其他方式均为相机、图库、文件管理器等混合选择项。
    • 自带浏览器打开均为文件管理器。

    由此说明此属性兼容性还是个问题。不过这并不能阻止我继续折腾下去!

    图片压缩

    在如今这个手机普遍千万像素的时代,一张照片动辄5M的大小。作为一个良心的开发者,我们是要为用户的流量负责的。
    该怎么做?我也不知道。大家都在用canvas实现,我也就用了。

    document.getElementById('file').addEventListener('change', function() {
        var reader = new FileReader();
        reader.onload = function (e) {
            compress(this.result);
        };
        reader.readAsDataURL(this.files[0]);
    }, false);

    不管文件域是用何种方式打开的,都可以在 change 事件中获取到选择的文件或拍摄的照片。

    创建一个FileReader对象,我们需要调用readAsDataURL把文件转换为base64图像编码,如data:image/jpeg;base64……这种格式。
    onload是一个异步回调,当文件读取完执行该方法内代码。this.result记录读取结果,如果读取失败,该值为null。在这里进行图片压缩的具体操作。

    var compress = function (res) {
        var img = new Image(),
            maxH = 160;
        img.onload = function () {
            var cvs = document.createElement('canvas'),
                ctx = cvs.getContext('2d');
            if(img.height > maxH) {
                img.width *= maxH / img.height;
                img.height = maxH;
            }
            cvs.width = img.width;
            cvs.height = img.height;
            ctx.clearRect(0, 0, cvs.width, cvs.height);
            ctx.drawImage(img, 0, 0, img.width, img.height);
            var dataUrl = cvs.toDataURL('image/jpeg', 0.6);
            // 上传略
        }
        img.src = res;
    }

    创建一个Image对象,给src属性赋值为读取结果,同样在onload异步回调中编写处理图片的代码。
    这里就要开始使用canvas进行图片压缩了。

    首先是尺寸按比例缩放,然后把图片绘到画布上,最后调用toDataURL方法压缩图像质量。

    context.toDataURL('MIME类型', 图像质量0-1);  // 该方法返回base64图像编码

    代码里省略了一些校监操作,如文件类型约束和文件大小判断(小于一定值可以不压缩)。
    最后就是把数据发送到后端的操作,这里就不说了。

    Html5调用摄像头

    通过以上的代码已经可以实现调用手机相机拍照、压缩、上传这一整套流程了。
    不过在折腾的过程中也发现了一种调用摄像头的方法。注意,是摄像头!使用input调用的是相机。其中的差别就是摄像头是只捕获画面,相机还包括原生的一些拍照、设置等控件。

    通过对摄像头的调用可以做很多有趣的事,比如拍照美化、滤镜等。可以说实现一个第三方相机是没问题的。
    之前下载过一款安卓相机APP,不到100K的大小,可以实现拍照的一些风格化,也许就是Html5实现的呢。

    需要用到的是 getUserMedia API,具体的实现这里就不贴了。

    【用到的HTML5标签】

    <input type="file" capture="camera" accept="image/*" id="cameraInput" name="cameraInput" class="sign_file"/>

    【等比缩放图片】

    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);
    }

    FileReader对象是用来解析file控件获取的本地图片地址的,具体介绍请百度一下。把解析好的地址设置给IMG标签的SRC属性,然后通过canvas对象把图片绘制; 在这过程中就有个等比缩放的算法,再用drawImage方法把图像画到canvas中。
    【如何获取画好的图片数据传到后端处理】
    通过 canvas.toDataURL(‘image/jpeg’,0.5)就可以获取到base64编码值,然后你就可以按照传统的POST或者AJAX方式处理了。

    【让图片显示】

    document.querySelector('input[type=file]').onchange = function() {
        var file = input.files[0];
        drawOnCanvas(file);
    };

    【后台处理方式】

    $base64 = $_POST['formFile'];
    $IMG = base64_decode( $base64 );
    file_put_contents('1.png', $IMG );
    根传统的上传图片不同,这时候后台需要用base64_decode解码
  • 相关阅读:
    To select the file to upload we can use the standard HTML input control of type
    Cascading Menu Script using Javascript Explained
    网站首页head区代码规范
    轻松掌握 Java 泛型
    JDK 5.0 中的泛型类型学习
    如何在firefox下获取下列框选中option的text
    是同步方法还是 synchronized 代码? 详解多线程同步规则
    javascript select option对象总结
    Select的动态取值(Text,value),添加,删除。兼容IE,FireFox
    javascript在ie和firefox下的一些差异
  • 原文地址:https://www.cnblogs.com/zhaoyingjie/p/8450180.html
Copyright © 2011-2022 走看看