html5调用手机相机并压缩、上传
近日刚做的一个功能,要在app里使用内嵌页面进行图像的上传。
从功能上看,原生的实现应该是最好的。毕竟页面上所有的东西都隔着一个浏览器,所有的实现都要依赖浏览器提供的接口,不同的浏览器对接口的实现又有差异……到最后又会陷入兼容性的大坑!
吐槽归吐槽,但是折腾的劲头不能丢!
使用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标签】
1
|
< input type = "file" capture = "camera" accept = "image/*" id = "cameraInput" name = "cameraInput" class = "sign_file" /> |
【等比缩放图片】
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
|
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方式处理了。
【让图片显示】
1
2
3
4
|
document.querySelector( 'input[type=file]' ).onchange = function () { var file = input.files[0]; drawOnCanvas(file); }; |
【后台处理方式】
1
2
3
|
$base64 = $_POST [ 'formFile' ]; $IMG = base64_decode ( $base64 ); file_put_contents ( '1.png' , $IMG ); |
根传统的上传图片不同,这时候后台需要用base64_decode解码
html5调用手机相机并压缩、上传的更多相关文章
- vue实现PC端调用摄像头拍照人脸录入、移动端调用手机前置摄像头人脸录入、及图片旋转矫正、压缩上传base64格式/文件格式
进入正题 1. PC端调用摄像头拍照上传base64格式到后台,这个没什么花里胡哨的骚操作,直接看代码 (canvas + video) <template> <div> &l ...
- HTML5 图片本地压缩上传插件「localResizeIMG」
移动应用中用户往往需要上传照片,但是用户上传的照片尺寸通常很大,而手机的流量却很有限,所以在上传前对图像进行压缩是很有必要的. 原生应用可以直接对文件进行处理,网页应用就没有这个优势了.不过 canv ...
- Html5+asp.net mvc 图片压缩上传
在做图片上传时,大图片如果没有压缩直接上传时间会非常长,因为有的图片太大,传到服务器上再压缩太慢了,而且损耗流量. 思路是将图片抽样显示在canvas上,然后用通过canvas.toDataURL方法 ...
- H5图片压缩上传
1.所用到技术 HTML5 API:filereader.canvas 以及 formdata 目前来说,HTML5的各种新API都在移动端的webkit上得到了较好的实现.本次使用到的FileRea ...
- 三款不错的图片压缩上传插件(webuploader+localResizeIMG4+LUploader)
涉及到网页图片的交互,少不了图片的压缩上传,相关的插件有很多,相信大家都有用过,这里我就推荐三款,至于好处就仁者见仁喽: 1.名气最高的WebUploader,由Baidu FEX 团队开发,以H5为 ...
- js 图片压缩上传(纯js的质量压缩,非长宽压缩)
下面是大神整理的demo,很实用,这里存一下备用,感谢大神! 此demo为大于1M对图片进行压缩上传 若小于1M则原图上传,可以根据自己实际需求更改. demo源码如下 <!DOCTYPE ht ...
- tinypng upload一键压缩上传工具,告别人肉
地址 项目地址:tinypng-upload 有兴趣的可以玩一玩,因为平时经常会用到图片压缩,上传,如果你也觉得很繁琐的话,这个将会解决你的痛点. 关于 tinypng-upload 这是一个基于 e ...
- 前端图片压缩上传(纯js的质量压缩,非长宽压缩)
此demo为大于1M对图片进行压缩上传 若小于1M则原图上传,可以根据自己实际需求更改. demo源码如下: <!DOCTYPE html> <html> <head&g ...
- 基于vue + axios + lrz.js 微信端图片压缩上传
业务场景 微信端项目是基于Vux + Axios构建的,关于图片上传的业务场景有以下几点需求: 1.单张图片上传(如个人头像,实名认证等业务) 2.多张图片上传(如某类工单记录) 3.上传图片时期望能 ...
随机推荐
- 按键消抖-----verilog
实际系统中常用的按键大部分都是轻触式按键,如下图所示.该按键内部由一个弹簧片和两个固定触点组成,当弹簧片被按下,则两个固定触点接通,按键闭合.弹簧片松开,两个触点断开,按键也就断开了.根据这种按键的机 ...
- OpenCv,EmguCv及.net之间的互动(The Interaction of OpenCv, EmguCv AND .net)
http://www.cnblogs.com/xrwang/archive/2010/01/26/TheInteractionOfOpenCv-EmguCvANDDotNet.html 前言 在.ne ...
- JQ 练习题
1.留言板 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w ...
- ASP.NET MVC Json()处理大数据异常解决方法,字符串的长度超过了为 maxJsonLength
问题: 使用 JSON JavaScriptSerializer 进行序列化或反序列化时出错.字符串的长度超过了为 maxJsonLength 属性设置的值. <system.web.exten ...
- Delphi中的基础数据类型
参考http://www.cnblogs.com/del/archive/2007/12/04/982167.html 在学习之初,在这么多的数据类型中,最好记住这五种标准数据类型(整型.实型.字符型 ...
- 使用JDBC的addBatch()方法提高效率
在批量更新SQL操作的时候建议使用addBatch,这样效率是高些,数据量越大越能体现出来 Statement接口里有两个方法:void addBatch(String sql)将给定的 SQ ...
- 一个简单的Promise 实现
用了这么长时间的promise,也看了很多关于promise 的文章博客,对promise 算是些了解.但是要更深的理解promise,最好的办法还是自己实现一个. 我大概清楚promise 是对异步 ...
- Microsoft SQL Server 博客目录
基础概念篇 SQL Server排序规则 SQL SERVER 统计信息概述(Statistics) SQL SERVER 索引之聚集索引和非聚集索引的描述 Sql Server 索引之唯一索引和筛选 ...
- 使用git进行团队合作开发
1.git 和 svn 的差异 git和svn 最大的差异在于git是分布式的管理方式而svn是集中式的管理方式.如果不习惯用代码管理工具,可能比较难理解分布式管理和集中式管理的概念.下面介绍两种工具 ...
- eclipse项目中关于导入的项目里提示HttpServletRequest 不能引用的解决办法
eclipse项目中关于导入的项目里提示HttpServletRequest 不能引用的解决办法 当使用eclipse导入外部的web工程时,有时会提示HttpServletRequest, Serv ...