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为 ...
随机推荐
- OpenTK教程-0序言
记得很久之前,我写过一个基于.NET的3D开发框架/工具比较.当时选定的技术是WPF.但是随着项目发展,需要处理的图形数量越来越多,基于WPF的处理起来性能有问题,最后还是使用了基于OpenTK的解决 ...
- 稀疏分解中的MP与OMP算法
MP:matching pursuit匹配追踪 OMP:正交匹配追踪 主要介绍MP与OMP算法的思想与流程,解释为什么需要引入正交? !!今天发现一个重大问题,是在读了博主的正交匹配追踪(OMP)在稀 ...
- 【转】JAVA处理线程超时
在实际业务中,由其是多线程并开业务中,经常会遇到某个线程执行超时.而程序如果不捕获这类情况,就会导致程序一直处于等待状态,从而影响后续线程的运行.比如说网络通迅.单任务下的复杂数据库查询等,通常处理这 ...
- 学习Git的最佳资料
1. ProGit中文版:https://git-scm.com/book/zh/v2 2. 廖雪峰的Git教程: http://www.liaoxuefeng.com/wiki/0013739516 ...
- 小白的Python之路 day4 装饰器前奏
装饰器前奏: 一.定义: 1.装饰器本质是函数,语法都是用def去定义的 (函数的目的:他需要完成特定的功能) 2.装饰器的功能:就是装饰其他函数(就是为其他函数添加附加功能) 二.原则: 1. 不能 ...
- 【java API基本实现】LinkedList
LinkedList: package com.tn.arraylist; public class LinkedList { Node head=null; Node tail=null; int ...
- 使用SplitContainer来实现隐藏窗口的部分内容(转)
有两种方法: (1) Splitter:比较老的方法 (2) SplitContainer:比较新的方法 最终界面如下: 方法一:使用Splitter实现 (1) 在窗口中添加一个Panel控件,即P ...
- 平方根的C语言实现(二) —— 手算平方根的原理
版权申明:本文为博主窗户(Colin Cai)原创,欢迎转帖.如要转贴,必须注明原文网址 http://www.cnblogs.com/Colin-Cai/p/7220506.html 作者:窗户 Q ...
- ArcGIS API for JavaScript 4.2学习笔记[12] View的弹窗(Popup)
看本文前最好对第二章(Mapping and Views)中的Map和View类有理解. 视图类有一个属性是Popup类型的popup,查阅API知道这个就是视图的弹窗,每一个View的实例都有一个p ...
- CDQ分治与整体二分小结
前言 这是一波强行总结. 下面是一波瞎比比. 这几天做了几道CDQ/整体二分,感觉自己做题速度好慢啊. 很多很显然的东西都看不出来 分治分不出来 打不出来 调不对 上午下午晚上的效率完全不一样啊. 完 ...