H5 调用本地相机并压缩上传(是从angular的ionic项目中截取的)
html部分
<div class="list_upload item bg_white">
<div class="itemImg pic_upload" ng-repeat="item in thumb">
<!-- 采用angular循环的方式,对存入thumb的图片进行展示 -->
<img ng-src="{{item.imgSrc}}" alt=""/>
<span class="itemImgClose" ng-if="item.imgSrc" ng-click="img_del($index)"><i class="ion-android-close"></i></span>
</div>
<div class="item_file" ng-repeat="item in thumb_default" ng-if="addImg">
<!-- 这里之所以写个循环,是为了后期万一需要多个‘加号’框 -->
<div class="item pic_upload"> <i class="icon ion-android-add"></i>
添加图片<input type="file" id="one-input" accept="image/*" file-model="images" onchange="angular.element(this).scope().img_upload(this.files)"/>
</div>
</div>
13 </div>
js部分
$scope.reader = new FileReader(); //创建一个FileReader接口
$scope.thumb = {}; //用于存放图片的base64
$scope.imagNmae = [];
//监听照片的变化
console.log($scope.thumb);
$scope.thumb_default = { //用于循环默认的‘加号’添加图片的框
1111:{}
};
//用于压缩图片的canvas
var canvas = document.createElement("canvas");
var ctx = canvas.getContext('2d');
//瓦片canvas
var tCanvas = document.createElement("canvas");
var tctx = tCanvas.getContext("2d");
//ionic post请求头部
var transFn = function (obj) {
return $httpParamSerializerJQLike(obj);
},
postCfg = {
headers: {'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'},
transformRequest:transFn
};
var flag = 0; //标志位
$scope.addImg = true;
var maxSize = 100*1024; //图片大小为100kb
$scope.img_upload = function(files) { //单次提交图片的函数
flag++;
var size = files[0].size / 1024 > 1024 ? (~~(10 * files[0].size / 1024 / 1024)) / 10 + "MB" : ~~(files[0].size / 1024) + "KB";
$scope.guid = (new Date()).valueOf(); //通过时间戳创建一个随机数,作为键名使用
$scope.reader.readAsDataURL(files[0]); //FileReader的方法,把图片转成base64
$scope.reader.onload = function (ev) {
$scope.$apply(function () {
$scope.thumb[$scope.guid] = {
imgSrc: ev.target.result, //接收base64
}
});
//上传图片的调用
var result = this.result;
var img = new Image();
img.src = result;
if (result.length <= maxSize) {
upload(result, files[0].type);
return;
}
//图片加载完毕之后进行压缩,然后上传
if (img.complete) {
callback();
} else {
img.onload = callback;
}
function callback() {
var data = compress(img);
upload(data, files[0].type);
img = null;
}
};
//判断图片的数量
if(flag >= 3){
$scope.addImg = false;
}
}; $scope.img_del = function(key) { //删除,删除的时候thumb和form里面的图片数据都要删除,避免提交不必要的
flag--;
console.log(key);
var guidArr = [],ImgId = [];
for(var p in $scope.thumb){
guidArr.push(p);
}
delete $scope.thumb[guidArr[key]]; //删除图片
for(var s in $scope.imagNmae){
ImgId.push(s);
}
delete $scope.imagNmae[ImgId[key]]; //删除图片id
if(flag < 3){
$scope.addImg = true;
}
}; //使用canvas对大图片进行压缩
var compress = function(img) {
var initSize = img.src.length;
var width = img.width;
var height = img.height;
//如果图片大于四百万像素,计算压缩比并将大小压至400万以下
var ratio;
if ((ratio = width * height / 4000000) > 1) {
ratio = Math.sqrt(ratio);
width /= ratio;
height /= ratio;
} else {
ratio = 1;
}
canvas.width = width;
canvas.height = height;
//铺底色
ctx.fillStyle = "#fff";
ctx.fillRect(0, 0, canvas.width, canvas.height);
//如果图片像素大于100万则使用瓦片绘制
var count;
if ((count = width * height / 1000000) > 1) {
count = ~~(Math.sqrt(count) + 1); //计算要分成多少块瓦片
//计算每块瓦片的宽和高
var nw = ~~(width / count);
var nh = ~~(height / count);
tCanvas.width = nw;
tCanvas.height = nh;
for (var i = 0; i < count; i++) {
for (var j = 0; j < count; j++) {
tctx.drawImage(img, i * nw * ratio, j * nh * ratio, nw * ratio, nh * ratio, 0, 0, nw, nh);
ctx.drawImage(tCanvas, i * nw, j * nh, nw, nh);
}
}
} else {
ctx.drawImage(img, 0, 0, width, height);
}
//进行最小压缩
var ndata = canvas.toDataURL('image/jpeg', 0.1);
//console.log('压缩前:' + initSize);
// console.log('压缩后:' + ndata.length);
//console.log('压缩率:' + ~~(100 * (initSize - ndata.length) / initSize) + "%");
tCanvas.width = tCanvas.height = canvas.width = canvas.height = 0;
return ndata;
};
//图片上传,
var upload = function (basestr,type) {
var text = basestr.split(",")[1]; //截取图片字节流
var obj = {
"参数名":"参数"
};
$http.post("接口链接",obj,postCfg).success(function (data) { }).error(function(err){
$scope.loadMore = true;
$ionicLoading.show({
template: "无法加载数据。请稍后再试。",
duration: 2000
});
});
};
效果展示

参考友情链接:
1、https://github.com/whxaxes/node-test/blob/master/server/upload/index_2.html
2、https://github.com/whxaxes/node-test/blob/master/server/upload/upload_2.js
3、http://www.cnblogs.com/jach/p/5734920.html
H5 调用本地相机并压缩上传(是从angular的ionic项目中截取的)的更多相关文章
- 基于H5+ API手机相册图片压缩上传
// 母函数 function App(){} /** * 图片压缩,默认同比例压缩 * @param {Object} path * pc端传入的路径可以为相对路径,但是在移动端上必须传入的路径是照 ...
- js实现本地的图片压缩上传预览
js在设计时考虑到安全的原因是不允许读写本地文件的,随着html5的出现提供了fileReader AP从而可以I实现本地图片的读取预览功能, 另外在移动端有的限制图片大小的需求,主要是考虑图片过大会 ...
- Nexus-在项目中使用Maven私服,Deploy到私服、上传第三方jar包、在项目中使用私服jar包
场景 Ubuntu Server 上使用Docker Compose 部署Nexus(图文教程): https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/ ...
- vue实现PC端调用摄像头拍照人脸录入、移动端调用手机前置摄像头人脸录入、及图片旋转矫正、压缩上传base64格式/文件格式
进入正题 1. PC端调用摄像头拍照上传base64格式到后台,这个没什么花里胡哨的骚操作,直接看代码 (canvas + video) <template> <div> &l ...
- 移动端H5上传图片并压缩上传
手头上的这个项目主要是在微信内运行的一个网站,需要用户上传手机内的照片,而现在手机照片尺寸越来越大,直接上传的话的确上传进度慢影响用户体验而且也会给服务器增加压力,所以利用H5的新特性压缩后上传不失为 ...
- Vue directive自定义指令+canvas实现H5图片压缩上传-Base64格式
前言 最近优化项目-手机拍照图片太大,回显速度比较慢,使用了vue的自定义指令实现H5压缩上传base64格式的图片 canvas自定义指令 Vue.directive("canvas&qu ...
- HTML5 图片本地压缩上传插件「localResizeIMG」
移动应用中用户往往需要上传照片,但是用户上传的照片尺寸通常很大,而手机的流量却很有限,所以在上传前对图像进行压缩是很有必要的. 原生应用可以直接对文件进行处理,网页应用就没有这个优势了.不过 canv ...
- 基于vue + axios + lrz.js 微信端图片压缩上传
业务场景 微信端项目是基于Vux + Axios构建的,关于图片上传的业务场景有以下几点需求: 1.单张图片上传(如个人头像,实名认证等业务) 2.多张图片上传(如某类工单记录) 3.上传图片时期望能 ...
- 三款不错的图片压缩上传插件(webuploader+localResizeIMG4+LUploader)
涉及到网页图片的交互,少不了图片的压缩上传,相关的插件有很多,相信大家都有用过,这里我就推荐三款,至于好处就仁者见仁喽: 1.名气最高的WebUploader,由Baidu FEX 团队开发,以H5为 ...
随机推荐
- 服务器固件测试--PCI设备的介绍(集成网卡和外插网卡)
今天2017年9月26号,快三个月的时间,是该梳理一下,我来到这个岗位学到的东西. 网卡是什么 网卡分为俩大类 板载的集成网卡和外插的网卡.外插的网卡又分为很多种. 板载的集成网卡 外插的网卡分为 I ...
- Java中进制的转换函数
十进制转成十六进制: Integer.toHexString(int i) 十进制转成八进制 Integer.toOctalString(int i) 十进制转成二进制 Integer.toBinar ...
- python运算符优先级问题
附上 对于or与and运算 其一, 在不加括号时候, and优先级大于or 其二, x or y 的值只可能是x或y. x为真就是x, x为假就是y 第三, x and y 的值只可能是x或y. x为 ...
- 《C++程序设计语言(十周年纪念版)》【PDF】下载
<C++程序设计语言(十周年纪念版)>[PDF]下载链接: https://u253469.pipipan.com/fs/253469-230382171 内容简介 <C++程序设计 ...
- Android studio导入eclipse项目(亲测)
之前上网搜索的时候,网上都说先用eclipse导出gradle,之后再用Android Studio的import project导入,但是这个方法使用的过程中会出现许多错误,解决了一个又一个还是不得 ...
- 20行JS代码实现贪吃蛇
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- Linux发行版 CentOS6.5下的分区操作
本文地址http://comexchan.cnblogs.com/ ,尊重知识产权,转载请注明出处,谢谢! 查询磁盘信息并作分区规划 执行下述命令查询磁盘信息: fdisk -l 可知.数据盘大小50 ...
- redis资料收集
http://www.runoob.com/redis/redis-sets.html redis set 使用 https://www.cnblogs.com/wanzaixiaoxin/p/49 ...
- 正则表达过滤表单隐藏元素,组装post数据
<form name="form1" action="'.$serverUrl.'" method="post" > <i ...
- mybatis的知识点
mybatis核心配置文件的配置 <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE conf ...