js等比压缩上传
一、js文件,这个是封装过的,借用了网络上的代码然后修改的
(function(window,undefined){ var upload = function(){
this.init();
}; upload.prototype={
init:function(){
var inputDom = document.createElement("input");
inputDom.type = "file";
inputDom.setAttribute("accept","image/*");
inputDom.setAttribute("multiple","multiple");
this.inputDom = inputDom;
this.bindChange();
},
start:function(o){
this.opt = this.setOpt(o);
this.inputDom.value = "";
this.canvasBefore();
this.inputDom.click();
},
bindChange:function(){
var dom = this.inputDom;
var that = this;
dom.onchange = function() {
try{ if (!this.files.length) return;
var files = Array.prototype.slice.call(this.files);
if (files.length > 1) {
alert("最多只可上传1张图片");
return;
} _shade_layer.show("上传中,请稍后...");
files.forEach(function(file, i) {
if (!/\/(?:jpeg|png|gif)/i.test(file.type)) return;
var reader = new FileReader(); //获取图片大小
var size = file.size / 1024 > 1024 ? (~~ (10 * file.size / 1024 / 1024)) / 10 + "MB": ~~ (file.size / 1024) + "KB"; reader.onload = function() {
var result = this.result;
var img = new Image();
img.src = result; //超出大小
if(result.length > that.opt.maxSize){
alert("图片大小不能超过5M");
_shade_layer.hide();
return;
} //如果图片大小小于100kb,则直接上传
if (result.length <= that.opt.minSize) {
img = null;
that.upload(result, file.type);
return;
}
//图片加载完毕之后进行压缩,然后上传
if (img.complete) {
callback();
} else {
img.onload = callback;
}
function callback() {
var data = that.compress(img);
that.upload(data, file.type);
img = null;
}
};
reader.readAsDataURL(file);
}) }catch(e){
_shade_layer.hide();
alert("上传出现错误");
return ;
}
};
},
/**
* 绘制压缩图片的canvas
*/
canvasBefore:function(){
var canvasDom = document.getElementById("canvas_id");
if(canvasDom){canvasDom.parent().remove();} var tCanvasDom = document.getElementById("tCanvas_id");
if(tCanvasDom){tCanvasDom.parent().remove();} //用于压缩图片的canvas
var canvas = document.createElement("canvas");
canvas.id = "canvas_id";
this.canvas = canvas;
this.ctx = canvas.getContext('2d'); //瓦片canvas
var tCanvas = document.createElement("canvas");
tCanvas.id = "tCanvas_id";
this.tCanvas = tCanvas;
this.tctx = tCanvas.getContext("2d");
},
/**
* 使用canvas对大图片进行压缩
* @param {} img 图片对象
* @return {}
*/
compress:function(img) {
var canvas = this.canvas;
var tCanvas = this.tCanvas;
var tctx = this.tctx;
var ctx = this.ctx; 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', this.opt.proportion);
/*
console.log('压缩前:' + initSize);
console.log('压缩后:' + ndata.length);
console.log('压缩率:' + ~~ (100 * (initSize - ndata.length) / initSize) + "%");
*/
tCanvas.width = tCanvas.height = canvas.width = canvas.height = 0; this.canvas = canvas;
this.tCanvas = tCanvas;
this.tctx = tctx;
this.ctx = ctx;
return ndata;
},
/**
* 获取blob对象的兼容性写法
* @param buffer
* @param format
* @returns {*}
*/
getBlob:function(buffer, format) {
try {
return new Blob(buffer, {
type: format
});
} catch(e) {
var bb = new(window.BlobBuilder || window.WebKitBlobBuilder || window.MSBlobBuilder);
buffer.forEach(function(buf) {
bb.append(buf);
});
return bb.getBlob(format);
}
},
/**
* 获取formdata
* @return {}
*/
getFormData:function() {
var isNeedShim = ~navigator.userAgent.indexOf('Android') && ~navigator.vendor.indexOf('Google') && !~navigator.userAgent.indexOf('Chrome') && navigator.userAgent.match(/AppleWebKit\/(\d+)/).pop() <= 534;
return isNeedShim ? new this.FormDataShim() : new FormData();
},
/**
* formdata 补丁, 给不支持formdata上传blob的android机打补丁
*/
FormDataShim:function() {
var o = this,
parts = [],
boundary = Array(21).join('-') + ( + new Date() * (1e16 * Math.random())).toString(36),
oldSend = XMLHttpRequest.prototype.send;
this.append = function(name, value, filename) {
parts.push('--' + boundary + '\r\nContent-Disposition: form-data; name="' + name + '"');
if (value instanceof Blob) {
parts.push('; filename="' + (filename || 'blob') + '"\r\nContent-Type: ' + value.type + '\r\n\r\n');
parts.push(value);
} else {
parts.push('\r\n\r\n' + value);
}
parts.push('\r\n');
}; // Override XHR send()
XMLHttpRequest.prototype.send = function(val) {
var fr, data, oXHR = this;
if (val === o) {
// Append the final boundary string
parts.push('--' + boundary + '--\r\n');
// Create the blob
data = getBlob(parts);
// Set up and read the blob into an array to be sent
fr = new FileReader();
fr.onload = function() {
oldSend.call(oXHR, fr.result);
};
fr.onerror = function(err) {
throw err;
};
fr.readAsArrayBuffer(data);
// Set the multipart content type and boudary
this.setRequestHeader('Content-Type', 'multipart/form-data; boundary=' + boundary);
XMLHttpRequest.prototype.send = oldSend;
} else {
oldSend.call(this, val);
}
};
},
/**
* 图片上传,将base64的图片转成二进制对象,塞进formdata上传
* @param {} basestr
* @param {} type
* @param {} $li
*/
upload:function(basestr, type) {
var that = this;
var text = window.atob(basestr.split(",")[1]);
var buffer = new Uint8Array(text.length);
var pecent = 0,
loop = null;
for (var i = 0; i < text.length; i++) {
buffer[i] = text.charCodeAt(i);
}
var blob = this.getBlob([buffer], type);
var xhr = new XMLHttpRequest();
var formdata = this.getFormData();
formdata.append('imagefile', blob);
xhr.open('post', this.opt.uploadURL);
xhr.onreadystatechange = function() {
this.canvas = null;
this.tCanvas = null;
this.tctx = null;
this.ctx = null; var func = that.opt.callBackFunc;
var id = that.opt.id; var oDataObj = that.opt.oDataObj;
var nType = that.opt.nType;
var frameCallBackFunc = that.opt.frameCallBackFunc;
var strCallbackFunc = that.opt.strCallbackFunc;
oDataObj["strCallbackFunc"] = strCallbackFunc;
oDataObj["nType"] = nType; if (xhr.readyState == 4 && xhr.status == 200) {
var url = xhr.responseText || "";
console.log(url);
var nState = url.length == 0 ? -1 : 0;
var strMsg = url.length == 0 ? "上传失败" : url;
oDataObj["nState"] = nState;
oDataObj["strMsg"] = strMsg;
oDataObj = JSON.stringify(oDataObj);
eval(frameCallBackFunc+"('"+oDataObj+"')");
_shade_layer.hide();
} if(xhr.status != 200){
oDataObj["nState"] = -1;
oDataObj["strMsg"] = "上传失败";
oDataObj = JSON.stringify(oDataObj);
eval(frameCallBackFunc+"('"+oDataObj+"')");
_shade_layer.hide();
}
};
xhr.send(formdata); },setOpt:function(o){
var defaultOptions={
nType:'', //回调的不同类型,通过这个类型来改_plus.callbackuploadPicture里面对于回调的具体方法,其实主要就是控制最终回调函数的参数
minSize:100 * 1024, //最小为100kb,也就是说100kb以下的不压缩直接上传
maxSize:1024 * 1024 * 5, //最大为10M,也就是说100kb以下的不压缩直接上传
proportion:0.3, //压缩比例:从0-1之间
strCallbackFunc:'',
frameCallBackFunc:'',
oDataObj:{},
uploadURL:'http://pocketwap.xxx.com/Servlet/fileUpload.svl'
};
if(o && Object.prototype.toString.call(o)=='[object Object]')
{
for(var k in o)
{
defaultOptions[k]= typeof o[k]==='undefined' ? defaultOptions[k] : o[k];
}
}
return defaultOptions;
}
} window.upload=upload;
})(window,undefined) var _upload = new upload();
二、js页面使用如下:
_upload.start({
id:Id,
callBackFunc:strCallbackFunc //回调地址
});
三、服务端接收,这边因为是要统一上传到文件服务器,所以这里中转了一下,如果不需要中转,直接就可以在这里面处理就行
package com.xxx.businesscenter.web; import java.io.BufferedInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.List; import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.log4j.Logger; import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.cdoframework.cdolib.base.UUidGenerator; /**
* Servlet implementation class FileUploadServlet
*/
public class FileUploadServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
private Logger log=Logger.getLogger(ApplicationListener.class);
/**
* @see HttpServlet#HttpServlet()
*/
public FileUploadServlet() {
super();
// TODO Auto-generated constructor stub
} /**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
this.doPost(request, response);
} /**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub String strResult = "";
DiskFileItemFactory factory = new DiskFileItemFactory();
ServletFileUpload upload = new ServletFileUpload(factory);
try {
List<FileItem> items = upload.parseRequest(request);
if(items.size() > 0 ){
FileItem item = items.get(0);
if(!item.isFormField()){
strResult = uploadFile(item);
}
}
} catch (FileUploadException e) {
log.info(e);
} response.getWriter().print(strResult); } private String uploadFile(FileItem item) {
String contentType = item.getContentType();
String postfix = contentType.split("/")[1];
String result = "";
String end = "\r\n";
String twoHyphens = "--";
String boundary = "*****";
String newName = UUidGenerator.genenator() + "."+postfix;
String actionUrl = "http://file.xxx.com.cn/Servlet/fileUpload.svl";
BufferedInputStream bufin = null;
InputStream is = null;
try {
URL url = new URL(actionUrl);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setConnectTimeout(10000); //超时时间为10秒
conn.setDoInput(true);
conn.setDoOutput(true);
conn.setUseCaches(false);
conn.setRequestMethod("POST");
conn.setRequestProperty("Connection", "Keep-Alive");
conn.setRequestProperty("Charset", "UTF-8");
conn.setRequestProperty("Content-Type","multipart/form-data;boundary=" + boundary);
DataOutputStream ds = new DataOutputStream(conn.getOutputStream());
ds.writeBytes(twoHyphens + boundary + end);
ds.writeBytes("Content-Disposition: form-data; " + "name=\"file1\";filename=\"" + newName + "\"" + end);
ds.writeBytes("Content-Type:" + contentType + "\r\n\r\n"); bufin = new BufferedInputStream(item.getInputStream());
int bufferSize = 2048;
byte[] buffer = new byte[bufferSize];
int length = -1;
while ((length = bufin.read(buffer)) != -1) {
ds.write(buffer, 0, length);
}
ds.writeBytes(end);
ds.writeBytes(twoHyphens + boundary + twoHyphens + end);
bufin.close();
ds.flush(); //获取上传返回结果
int code = conn.getResponseCode();
is = conn.getInputStream();
int ch;
StringBuffer b = new StringBuffer();
while ((ch = is.read()) != -1) {
b.append((char) ch);
} String str = b.toString();
log.info("-------------------------"+str);
if (conn.getResponseCode() == 200) {
if(str.length() > 0 ){
JSONObject jObject = JSON.parseObject(str);
String strFilePath = (String) jObject.get("strFilePath");
String strFileName = (String) jObject.get("strFileName");
result = strFilePath+strFileName;
log.info("-------------------------图片上传地址="+result);
}
}else{
log.info("-------------------------上传失败code="+code);
} } catch (Exception e) {
log.info(e);
return result;
}finally{
try {
if(bufin!=null){
bufin.close();
}
if(is!=null){
is.close();
}
} catch (IOException e) {
log.info("-------------------------流关闭失败-------------------------");
e.printStackTrace();
}
}
return result;
} }
js等比压缩上传的更多相关文章
- 纯原生js移动端图片压缩上传插件
前段时间,同事又来咨询一个问题了,说手机端动不动拍照就好几M高清大图,上传服务器太慢,问问我有没有可以压缩图片并上传的js插件,当然手头上没有,别慌,我去网上搜一搜. 结果呢,呵呵...诶~又全是基于 ...
- js 图片压缩上传(纯js的质量压缩,非长宽压缩)
下面是大神整理的demo,很实用,这里存一下备用,感谢大神! 此demo为大于1M对图片进行压缩上传 若小于1M则原图上传,可以根据自己实际需求更改. demo源码如下 <!DOCTYPE ht ...
- 前端图片压缩上传(纯js的质量压缩,非长宽压缩)
此demo为大于1M对图片进行压缩上传 若小于1M则原图上传,可以根据自己实际需求更改. demo源码如下: <!DOCTYPE html> <html> <head&g ...
- 基于vue + axios + lrz.js 微信端图片压缩上传
业务场景 微信端项目是基于Vux + Axios构建的,关于图片上传的业务场景有以下几点需求: 1.单张图片上传(如个人头像,实名认证等业务) 2.多张图片上传(如某类工单记录) 3.上传图片时期望能 ...
- js 图片压缩上传(base64位)以及上传类型分类
一.input file上传类型 1.指明只需要图片 <input type="file" accept='image/*'> 2.指明需要多张图片 <input ...
- JS—图片压缩上传(单张)
*vue+webpack环境,这里的that指到vue实例 <input type="file" name="file" accept="ima ...
- 三款不错的图片压缩上传插件(webuploader+localResizeIMG4+LUploader)
涉及到网页图片的交互,少不了图片的压缩上传,相关的插件有很多,相信大家都有用过,这里我就推荐三款,至于好处就仁者见仁喽: 1.名气最高的WebUploader,由Baidu FEX 团队开发,以H5为 ...
- HTML5 图片本地压缩上传插件「localResizeIMG」
移动应用中用户往往需要上传照片,但是用户上传的照片尺寸通常很大,而手机的流量却很有限,所以在上传前对图像进行压缩是很有必要的. 原生应用可以直接对文件进行处理,网页应用就没有这个优势了.不过 canv ...
- Html5+asp.net mvc 图片压缩上传
在做图片上传时,大图片如果没有压缩直接上传时间会非常长,因为有的图片太大,传到服务器上再压缩太慢了,而且损耗流量. 思路是将图片抽样显示在canvas上,然后用通过canvas.toDataURL方法 ...
随机推荐
- Enable Scribble,Enable Guard Edges,Enable Guard Malloc,Zombie Objects
最近项目中使用一个翻拍身份证信息识别活体检测的第三方框架,在使用时会偶然性的出现崩溃的现象,经过查找是因为第三方框架中有释放的内存区域再次引用引起的,因而补充一下相关知识点. 在Xcode Edi ...
- Hystrix使用详解
原文参考:http://hot66hot.iteye.com/blog/2155036 一:为什么需要Hystrix? 在大中型分布式系统中,通常系统很多依赖(HTTP,hession,Netty,D ...
- Sourcetree报错: 您没有已经配置扩展集成设置的远端
一.错误提示 您没有已经配置扩展集成设置的远端; ... 二.解决 配置 Legacy Account Settings 即可:
- yii 修改模块使用的布局文件
方法一:yii模块默认使用系统当前的主题布局文件,如果在主配置文件中配置了主题比如: 'theme'=>'mythm', 那么yii的模块就使用 protected/themes/mythm/v ...
- drupal7 查看哪些模块实现了某个钩子
module_implements($hook) 可参考函数module_invoke_all function module_invoke_all($hook) { $args = func_get ...
- 转:Jquery如何获取某个元素前(后)的文本内容?
原文:[解决]Jquery如何获取某个元素前(后)的文本内容? <span> text here... <a id="target_element">百万创 ...
- cookie封装函数与使用方法(转)
函数封装: var Cookie = function(name, value, options) { // 如果第二个参数存在 if (typeof value != 'undefined') { ...
- mac上显示.开头的文件
第一种方法是在finder中按下command+shift+.键. 第二种方法是在命令行输入如下命令 defaults write com.apple.Finder AppleShowAllFiles ...
- [Asp.net mvc]Asp.net mvc 中使用LocalStorage
目前使用比较多的本地存储方案有比如Flash SharedObject.Google Gears.Cookie.LocalStorage.User Data.Open Database等方案.综合比较 ...
- [转载]Cool, Tomcat is able to handle more than 13,000 concurrent connections
Last time I have promised you to take a look at more real life scenario regarding threads. In the la ...