前几个月闲得无聊写得一段代码,没想最近刚好用上了,在硬盘里翻了半天找回来,还没好好整理直接用上了
手机用户拍照上传的图片一般都在1M 到4M 之间,如果只是用作头像尺寸就可以缩小很多,1M甚至几M的图转换成几百K。

<!doctype html>
<html>
<head>
<title>test</title>
<script src="js/zepto-master/src/zepto.min.js"></script>
<script>

/*****

by cnblogs.com/ecalf

**/

var uploadImg = (function($){

    function fileUpLoader(config){
if(typeof(config.field)=='string'){//input type=file
config.field = document.getElementById(config.field);
}
if(typeof(config.viewPane)=='string'){//预览图
config.viewPane = document.getElementById(config.viewPane);
}
if(typeof(config.uploadBtn)=='string'){//上传按钮
config.uploadBtn = document.getElementById(config.uploadBtn);
} this.afterSelectFile = config.afterSelectFile||function(){}; this.maxSize = config.maxSize==undefined?4194304:(config.maxSize||0);//maxSize 0 不限制大小 this.field = config.field;
this.viewPane = config.viewPane;
this.uploadBtn = config.uploadBtn;
if(config.uploadUrl){
this.uploadUrl = config.uploadUrl;
}
if(typeof(config.afterUpload)=='function'){
this.afterUpload = config.afterUpload;
}
if(Object(config.extParams)===config.extParams){
this.extParams = config.extParams;
} this.init();
}
fileUpLoader.prototype = {
init:function(){
this.domEvents();
console.log('uploadfile init');
},
domEvents:function(){
var host = this; if(host.field&&host.afterSelectFile){
$(host.field).on("change",function(e){
host.afterSelectFile&&host.afterSelectFile(this);
});
} if(host.uploadBtn){
$(host.uploadBtn).on('click',function(){
host.upload();
});
} }, imgToDataURL:function(img,type,typecallback,frag){
type = type||'image/png';
            var databack={
status:true,
dataURL:'',
callback:callback,
resolve:function(){
this.callback(this.dataURL);
}
} var trans = function(pic){//canvas.toDataURL,context.getImageData 不能读取跨域图片
pic.crossOrigin = "*";
var cvs = document.createElement("canvas");
document.body.appendChild(cvs);
var ctx = cvs.getContext('2d');
cvs.width = pic.width;
cvs.height = pic.height; console.log('img size:',pic.width+'px',pic.height+'px');
ctx.drawImage(pic,0,0,pic.width,pic.height);
var dataURL = cvs.toDataURL(type);
console.log('dataURL length:',dataURL.length)
cvs = null;
ctx = null; return dataURL;
}; if(!frag&&img.width&&img.height){ //img 加载完才能取出img的数据,如果在domReady 里面执行,图片未加载完会绘制出空白的 canvas
console.log('trans directly');
databack.dataURL = trans(img);
databack.resolve(); }else{//使用 图片的 natural size,img loaded后才能获得高宽
databack.status = false;
var pic = new Image();
pic.crossOrigin = "*";
pic.onload = function(e){
console.log('trans onload');
databack.dataURL = trans(e.target);
databack.status = true;
databack.resolve();
pic = null;
};
pic.src = img.src;
} return databack;
}, dataURLToBlob:function(dataURL){
console.log(dataURL.length)
var type = dataURL.match(/data:(.+?);/);
type = type?type[1]:'image/png';
var dataContent = dataURL.replace(/^.+,/,'');
dataContent = atob(dataContent);
var dataCharCode = [];
var i = 0;
while(i<dataContent.length){
dataCharCode[i] = dataContent.charCodeAt(i);
i++;
}
var u8Arr = new Uint8Array(dataCharCode);
return new Blob([u8Arr],{type:type}); // you maybe use new BolbBuilder() in older browser, maybe canvas.toBlob() is better for image }, readURL:function (input,callback) {//创建预览图
input = input||this.field;
if (input.files && input.files[0]) {
if(this.maxSize&&input.files[0].size > this.maxSize){
alert('文件大于'+(this.maxSize/(1024*1024))+'m,请重新上传');
return false;
} var reader = new FileReader();
reader.onload = function (e) {
callback&&callback(e.target.result);
};
var dataUrl = reader.readAsDataURL(input.files[0]);
reader = null;
return dataUrl;
}
}, upload:function(fileConfig){
var host = this;
var formData = new FormData();
var file,name,filename;
if(!fileConfig){
name = host.field.name;
file = host.field.files[0];
filename = host.field.value.split(/[/\\]/).pop()||"temp.png";
}else{
name = fileConfig.name;
file = fileConfig.file;
filename = fileConfig.filename||"temp.png";
} if(!file){
console.log('no file');
} formData.append(name,file,filename); if(Object(host.extParams)===host.extParams){
$.each(host.extParams,function(k,v){
formData.append(k,v);
});
} $.ajax({
url: host.uploadUrl,
type: 'POST',
data: formData,
async: true,
dataType:'json',
cache: false,
contentType: false,
processData: false,
timeout:45000,
success: function (data,status, xhr) {
host.afterUpload&&host.afterUpload(data); },
error:function(xhr, errorType, error){
console.log(errorType, error);
},
complete:function(xhr, status){
console.log('post complete,status:',status);
}
}); }//end upload
}; return {
init:function(config){
return new fileUpLoader(config);
}
}; })(Zepto); $(document).ready(function(){
upload = uploadImg.init({
field:'uploadimg',
viewPane:'viewPane',
uploadBtn:'submitbtn',
uploadUrl:'yourimguploadurl.jsp',
maxSize:0,
afterUpload:function(resp){ },
extParams:{uid:12}
}); window.onload = function(){
var img = document.querySelector("img");
upload.imgToDataURL(img,'image/jpeg',function(DataURL){
var blob = upload.dataURLToBlob(DataURL);
console.log(blob);
},true);
}; $("#uploadimg").on("change",function(){
var file = this.files[0];
if(!file){ return; } upload.readURL(this,function(dataURL){
upload.viewPane&&(upload.viewPane.src = dataURL);
var img = new Image();
img.onload = function(){
var img = document.querySelector("img");
upload.imgToDataURL(img,'image/jpeg',function(dataURL){
var blob = upload.dataURLToBlob(dataURL);
console.log(blob);
},false);
}
img.src=dataURL; });
}); }); </script>
</head>
<body>
<div>
<img id="viewPane" width="800" height="600" src="img/1111.png" />
<form id="testform">
<!-- camera--照相机;camcorder--摄像机;microphone--录音 -->
<input id="uploadimg" type="file" accept="image/*" capture="camera" />
<input id="submitbtn" type="submit" />
</form> </div>
</body>
</html>

http://stackoverflow.com/questions/11929099/html5-canvas-drawimage-ratio-bug-ios

ios  下 canvas 的 drawImage 存在扭曲 bug (似乎是像素过大时出现),修复方法如下

        /** 修复 ios 下 canvas drawImage 函数的 画面扭曲BUG
* Detecting vertical squash in loaded image.
* Fixes a bug which squash image vertically while drawing into canvas for some images.
* This is a bug in iOS6 devices. This function from CodeGo.net
*
*/
function detectVerticalSquash(img) {
var iw = img.naturalWidth, ih = img.naturalHeight;
var canvas = document.createElement('canvas');
canvas.width = 1;
canvas.height = ih;
var ctx = canvas.getContext('2d');
ctx.drawImage(img, 0, 0);
var data = ctx.getImageData(0, 0, 1, ih).data;
// search image edge pixel position in case it is squashed vertically.
var sy = 0;
var ey = ih;
var py = ih;
while (py > sy) {
var alpha = data[(py - 1) * 4 + 3];
if (alpha === 0) {
ey = py;
} else {
sy = py;
}
py = (ey + sy) >> 1;
}
var ratio = (py / ih);
return (ratio===0)?1:ratio;
}
/**
* A replacement for context.drawImage
* (args are for source and destination).
* fixed: set height as height/vertSquashRatio
*/
function drawImageIOSFix(ctx, img, sx, sy, sw, sh, dx, dy, dw, dh) {
var vertSquashRatio = detectVerticalSquash(img);
ctx.drawImage(img, sx, sy, sw, sh, dx, dy, dw, dh / vertSquashRatio);
}

IOS 系统 safari 浏览器上开发 应注意的问题:

https://developer.apple.com/library/safari/documentation/AppleApplications/Reference/SafariWebContent/CreatingContentforSafarioniPhone/CreatingContentforSafarioniPhone.html#//apple_ref/doc/uid/TP40006482-SW15

js 预处理用户上传图片的更多相关文章

  1. Gremlins.js – 模拟用户随机操作的 JS 测试库

    Gremlins.js 是基于 JavaScript 编写的 Monkey 测试库,支持 Node.js 平台和浏览器中使用.Gremlins.js 随机模拟用户操作:单击窗口中的任意位置,在表格中输 ...

  2. Headroom.js – 快速响应用户的页面滚动操作

    Headroom.js 是一个轻量级,高性能的JS插件(无依赖性!),允许你响应用户的滚动行为.Headroom.js 使您能够在适当的时候把元素融入视图,而其它时候让内容成为焦点.Headroom. ...

  3. js记录用户在网站的浏览记录和停留时间

    by weber开发者 from http://weber.pub/ 本文地址: http://weber.pub/js记录用户行为浏览记录和停留时间/163.html 问题 公司想统计一个用户从进入 ...

  4. JS验证用户真实姓名

    发布:thebaby   来源:脚本学堂     [大 中 小] 本文分享下,使用js代码验证用户真实姓名的方法,有需要的朋友不妨参考下,希望对你有一定的帮助. 原文地址:http://www.jbx ...

  5. js记录用户行为浏览记录和停留时间(转)

    演示地址:http://weber.pub/demo/160902/test.html 测试源码下载:http://pan.baidu.com/s/1nvPKbSP 密码:r147 解决问题所使用的知 ...

  6. ajaxFileUpload.js 无刷新上传图片,支持多个参数同时上传,支持 ie6-ie10

    /* 131108-xxj-ajaxFileUpload.js 无刷新上传图片 jquery 插件,支持 ie6-ie10 依赖:jquery-1.6.1.min.js 主方法:ajaxFileUpl ...

  7. js判断用户是客户端还是移动端

    js判断用户是客户端还是移动端 Javascript 判断客户端是否为 PC 还是手持设备,有时候项目中需要用到,很方便的源生检测,方法一共有两种   1.第一种: function IsPC() { ...

  8. Vue.Js的用户体验优化

    一次基于Vue.Js的用户体验优化   一.写在前面 半年以前,第一次在项目上实践VueJs,由于在那之前,没有Angular,avalon等框架的实践经验,所以在Vue的使用上,没有给自己总结出更多 ...

  9. JS获取用户的Ip地址

    在网站中通常需要获取使用者的ip地址,获取抵制的方式有很多,这里就简单介绍一下js获取用户ip地址 /*使用的新浪的ip查询api,根据返回的数据进行判断*/ <script src=" ...

随机推荐

  1. squid 2.7 通过域名反向代理多个服务器的配置方法

    详细配置及注释如下,供大家学习参考. visible_hostname squid1.abc.com #设定squid的主机名,如无此项squid将无法启动 http_port 80 accel vh ...

  2. 给钛度产品的一些建议(Note)

    背景:上一只鼠标坏了,今天299从京东如了一只钛度鼠标,核心用料据说都很高端,设计也不错.但是实际用起来发现了很多码农常识问题和产品建议,遂反馈给钛度客服,并记录于此. 传送门: http://bbs ...

  3. Oracle 和 SqlServer 的区别

    --sql server 与  oracle的区别: --DBMS 数据库管理系统--1.数据类型不同.      --sql server 的数据类型:int ,smallint ,char,var ...

  4. javascript面向切面

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  5. 谈谈SQL 语句的优化技术

    https://blogs.msdn.microsoft.com/apgcdsd/2011/01/10/sql-1/ 一.引言 一个凸现在很多开发者或数据库管理员面前的问题是数据库系统的性能问题.性能 ...

  6. ppmoney 总结一

    1.JQ $.get() <!DOCTYPE html> <html lang="en"> <head> <meta charset=&q ...

  7. 重写AgileEAS.NET SOA 中间件平台账号密码的加密算法

    一.平台简介 AgileEAS.NET SOA 中间件平台是一款基于基于敏捷并行开发思想和Microsoft .Net构件(组件)开发技术而构建的一个快速开发应用平台.用于帮助中小型软件企业建立一条适 ...

  8. mysql忘记root密码怎么办?

    有时候忘记mysql的root密码了,怎么办? 这个时候,我们可以修改my.cnf,添加以不检查权限的方式启动,再修改root,最后重启mysql数据库. (1)service mysql stop ...

  9. Drools API的使用学习

    Drools API的使用学习在 Drools 当中,规则的编译与运行要通过 Drools 提供的各种 API 来实现,这些 API 总体来讲可以分为三类:规则编译.规则收集和规则的执行.完成这些工作 ...

  10. UVA 12300 Smallest Regular Polygon(正多边形)

    题意:给出两点,求经过这两点的正n边形的最小面积 题解:这两点一定是最长的弦,我们设正多边形中点c,找到c到每个点的距离(都相同) 我们知道那个等腰三角形的底与每个角度就使用余弦定理 #include ...