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.上传图片时期望能 ...
随机推荐
- 数据结构和算法 – 12.高级查找算法(下)
哈希(散列)技术既是一种存储方法,也是一种查找方法.然而它与线性表.树.图等结构不同的是,前面几种结构,数据元素之间都存在某种逻辑关系,可以用连线图示表示出来,而哈希技术的记录之间不存在什么逻辑关系, ...
- (编辑器)Jquery-EasyUI集合Kindeditor编辑器
1.在html里面添加 list.html list.html (function ($, K) { if (!K) throw "KindEditor未定义!"; functio ...
- 无废话ExtJs 入门教程十六[页面布局:Layout]
无废话ExtJs 入门教程十六[页面布局:Layout] extjs技术交流,欢迎加群(201926085) 首先解释什么是布局: 来自百度词典的官方解释:◎ 布局 bùjú: [distributi ...
- <转>JDBC获取DB元数据
原文链接:http://jiauwu.iteye.com/blog/1307617 package com.util.jdbc; import java.sql.Connection; import ...
- C语言字符串长度(转)
C语言字符串长度的计算是编程时常用到的,也是求职时必考的一项. C语言本身不限制字符串的长度,因而程序必须扫描完整个字符串后才能确定字符串的长度. 在程序里,一般会用strlen()函数或sizeof ...
- [Windows驱动开发](四)内存管理
一.内存管理概念 1. 物理内存概念(Physical Memory Address) PC上有三条总线,分别是数据总线.地址总线和控制总线.32位CPU的寻址能力为4GB(2的32次方)个字 ...
- h5嵌入视频遇到的bug及总结---转载
最近做的一个h5活动因为嵌入视频而发现了好多以前从未发现的问题,在测试的时候不同系统不同版本不同环境等多多少少都出现了些问题,搞得我也是焦头烂额的,不过好在最终问题都解决了,自己也学到了好多东西,为了 ...
- codeforces733D. Kostya the Sculptor 偏序cmp排序,数据结构hash,代码简化
对于n==100.1,1,2或者1,2,2大量重复的形状相同的数据,cmp函数最后一项如果表达式带等于,整个程序就会崩溃 还没有仔细分析std::sort的调用过程,所以这里不是很懂..,mark以后 ...
- ArrayList集合&特殊集合
一.ArrayList集合 集合内可以放不同类型的元素 另:object类型为所有数据类型的基类 添加元素:.add(); 清空集合:al.clear(); 克隆集合:.clone(); 判断是否包含 ...
- 删除表数据drop、truncate和delete的用法
说到删除表数据的关键字,大家记得最多的可能就是delete了 然而我们做数据库开发,读取数据库数据.对另外的两兄弟用得就比较少了 现在来介绍另外两个兄弟,都是删除表数据的,其实也是很容易理解的 老大- ...