超清晰!HTML5 实现手机拍照上传功能原理讲解

这篇文章主要为大家详细介绍如何使用HTML5利用摄像头拍照实现上传功能,原理讲解非常清晰,具有较大的参考价值。

超清晰!HTML5 实现手机拍照上传功能原理讲解

上传页面代码:

<style >
    *{
        padding: 0;
        margin: 0;
    }
    .wrapper{
        width: 320px;
        height: 50px;
        margin: 20px auto;
        position: relative;
        border: 1px solid #f0f0f0;
    }
    input{
        width: 100px;
        height: 30px;
    }
    button{
        position: absolute;
        cursor: pointer;
        pointer-events: none;
        width: 100px;
        height: 30px;
        left: 0;
        top: 0;
    }
    a{
        pointer-events: none;
    }
    .img{
        border: 1px solid #ccc;
        padding: 10px;
    }
</style >
 
<div class = "wrapper">
     <input type = "file" accept= "image/*" capture= "camera" id= "img" />
     <button >上传照片 </button >
</div >

上传图片用的HTML5的file文件上传功能<input type=”file” accept=”image/*”>

因为原生file样式不满足要求,在input上面放置我们想要的页面效果。然后当点击上面的元素,就可以触发我们的input进行图片上传。此时的问题是:当点击input上面的元素,需要事件穿透,即相当于点击input。则借助于css3新属性pointer-events。

//使用cursor进行事件穿透,来阻止元素成为鼠标事件的目标
button{
     cursor:pointer;
     pointer-events:none;
}

图片压缩处理

  1. 因为是手机拍照上传,现在的手机拍的照片都很大,如果原图上传,太消耗用户流量,上传前要进行图片压缩。
  2.   通过change事件,监听图片上传,通过readerAsDataURL获取上传的图片。
document.getElementById( 'img').addEventListener( 'change', function () {
     var reader = new FileReader();
     reader.onload = function (e) {
          //调用图片压缩方法:compress();
     };
     reader.readAsDataURL(this.files[0]);
     console.log(this.files[0]);
     var fileSize = Math.round( this.files[0].size/1024/1024) ; //以M为单位
     //this.files[0] 该信息包含:图片的大小,以byte计算 获取size的方法如下:this.files[0].size;
}, false);

 对上传的图片进行压缩,需要借助于canvas API,调用其中的canvas.toDataURL(type, encoderOptions); 将图片按照一定的压缩比进行压缩,得到base64编码。重点来了:压缩策略:先设置图片的最大宽度 or 最大高度,一般设置其中一个就可以了,因为所有的手机宽高比差别不是很大。然后设置图片的最大size,allowMaxSize,根据图片的实际大小和最大允许大小,设置相应的压缩比率。

//最终实现思路:
1、设置压缩后的最大宽度 or 高度;
2、设置压缩比例,根据图片的不同size大小,设置不同的压缩比。
 
function compress(res,fileSize) { //res代表上传的图片,fileSize大小图片的大小
    var img = new Image(),
        maxW = 640; //设置最大宽度
 
    img.onload = function () {
        var cvs = document.createElement( 'canvas'),
            ctx = cvs.getContext( '2d');
 
        if(img.width > maxW) {
            img.height *= maxW / img.width;
            img.width = maxW;
        }
 
        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 compressRate = getCompressRate(1,fileSize);
 
        var dataUrl = cvs.toDataURL( 'image/jpeg', compressRate);
 
        document.body.appendChild(cvs);
        console.log(dataUrl);
    }
 
    img.src = res;
}
 
function getCompressRate(allowMaxSize,fileSize){ //计算压缩比率,size单位为MB
      var compressRate = 1;
 
      if(fileSize/allowMaxSize > 4){
           compressRate = 0.5;
      } else if(fileSize/allowMaxSize >3){
           compressRate = 0.6;
      } else if(fileSize/allowMaxSize >2){
           compressRate = 0.7;
      } else if(fileSize > allowMaxSize){
           compressRate = 0.8;
      } else{
           compressRate = 0.9;
      }
 
      return compressRate;
}

图片上传给服务器

图片已经压缩完成了,但是压缩后的图片不是File,而是一个base64编码,需要以String的形式将base64编码上传给服务器,服务器转存base64为img图片。

125jz网原创文章。发布者:江山如画,转载请注明出处:http://www.125jz.com/10947.html

(1)
江山如画的头像江山如画管理团队
上一篇 2022年8月10日 下午9:14
下一篇 2022年8月11日 上午9:48

99%的人还看了以下文章

  • 【深度学习】:3分钟入门Dropout层

    深度神经网(DNN)中经常会存在一个常见的问题:模型只学会在训练集上分类(过拟合现象),dropout就是为了减少过拟合而研究出的一种方法。

    2023年1月15日
    7.6K0
  • Ubantu为应用程序添加桌面图标

    按要求配置应用程序参数,为应用程序添加桌面图标,实现系统快捷启动。 Ubuntu桌面的左边(默认在左边)有一个启动器,类似于window的任务栏。在Ubuntu18中叫dock(船坞),有时候又叫收藏夹。本文统一叫做启动器 在使用 Ubuntu 操作系统进行开发过程中,由于Ubuntu 系统其操作方式主要通过命令行终端进行交互,故启动软件也一般通过终端键入应…

    2022年9月1日 编程开发
    8.2K0
  • 跟永哥学MVC:jsp+javabean+servlet实现求圆的面积

    上一节课我们通过一个案例三种实现,教你理解Jsp、javabean、Servlet(精),今天我们仍然通过同一个案例求圆的面积,使用MVC:jsp+javabean+servlet来实现,深入理解MVC及Jsp、javabean、Servlet的分工和使用。 r5.jsp <form action=”servletCircle” Method=”pos…

    2018年2月22日
    8.5K0
  • String、StringBuffer、StringBuilder的区别?

    String在实例化之后,其内存空间的内容大小是不能够被修改的;而StringBuffer是一个线程安全的可变字符序列,在实例化之后可以动态的修改堆内存中的内容,所以内存长度和大小是可变的;StringBuilder实例化之后内存大小长度也是可变的,不同之处在于StringBuilder不是线程同步,因此操作起来必然比StringBuffer更加高效。

    2018年10月24日
    2.9K0
  • 推荐!一个通用的javaBean很方便的实现连接数据库、查询、插入、修改功能

    这是一个通用的javaBean,能够很方便的实现连接数据库、查询、插入、修改功能。、 package com.common; import java.sql.*; public class DataBaseConn { public Connection conn = null; public void createConn(){ String DRIVER…

    2020年12月6日
    3.4K0
  • 快来围观!微信小程序开发需要前期准备的信息整理出来了

    一、域名以及服务器 注册一个域名,域名必须进行ssl证书配置 域名进行备案 准备服务器可选择自主搭建机房,也可选择云服务器 二、注册微信小程序 1.在微信公众平台官网首页(mp.weixin.qq.com)点击右上角的“立即注册”按钮。 2.登陆微信公众平台https://mp.weixin.qq.com/ 点击注册->注册小程序 3.依次按照官方提示填写注…

    2022年9月19日 编程开发
    5.9K0

发表回复

登录后才能评论