一、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等比压缩上传的更多相关文章

  1. 纯原生js移动端图片压缩上传插件

    前段时间,同事又来咨询一个问题了,说手机端动不动拍照就好几M高清大图,上传服务器太慢,问问我有没有可以压缩图片并上传的js插件,当然手头上没有,别慌,我去网上搜一搜. 结果呢,呵呵...诶~又全是基于 ...

  2. js 图片压缩上传(纯js的质量压缩,非长宽压缩)

    下面是大神整理的demo,很实用,这里存一下备用,感谢大神! 此demo为大于1M对图片进行压缩上传 若小于1M则原图上传,可以根据自己实际需求更改. demo源码如下 <!DOCTYPE ht ...

  3. 前端图片压缩上传(纯js的质量压缩,非长宽压缩)

    此demo为大于1M对图片进行压缩上传 若小于1M则原图上传,可以根据自己实际需求更改. demo源码如下: <!DOCTYPE html> <html> <head&g ...

  4. 基于vue + axios + lrz.js 微信端图片压缩上传

    业务场景 微信端项目是基于Vux + Axios构建的,关于图片上传的业务场景有以下几点需求: 1.单张图片上传(如个人头像,实名认证等业务) 2.多张图片上传(如某类工单记录) 3.上传图片时期望能 ...

  5. js 图片压缩上传(base64位)以及上传类型分类

    一.input file上传类型 1.指明只需要图片 <input type="file" accept='image/*'> 2.指明需要多张图片 <input ...

  6. JS—图片压缩上传(单张)

    *vue+webpack环境,这里的that指到vue实例 <input type="file" name="file" accept="ima ...

  7. 三款不错的图片压缩上传插件(webuploader+localResizeIMG4+LUploader)

    涉及到网页图片的交互,少不了图片的压缩上传,相关的插件有很多,相信大家都有用过,这里我就推荐三款,至于好处就仁者见仁喽: 1.名气最高的WebUploader,由Baidu FEX 团队开发,以H5为 ...

  8. HTML5 图片本地压缩上传插件「localResizeIMG」

    移动应用中用户往往需要上传照片,但是用户上传的照片尺寸通常很大,而手机的流量却很有限,所以在上传前对图像进行压缩是很有必要的. 原生应用可以直接对文件进行处理,网页应用就没有这个优势了.不过 canv ...

  9. Html5+asp.net mvc 图片压缩上传

    在做图片上传时,大图片如果没有压缩直接上传时间会非常长,因为有的图片太大,传到服务器上再压缩太慢了,而且损耗流量. 思路是将图片抽样显示在canvas上,然后用通过canvas.toDataURL方法 ...

随机推荐

  1. 机器学习classification_report方法及precision精确率和recall召回率 说明

    classification_report简介 sklearn中的classification_report函数用于显示主要分类指标的文本报告.在报告中显示每个类的精确度,召回率,F1值等信息. 主要 ...

  2. AutoFac使用方法总结二:事件与依赖循环

         事件 AutoFac支持三种事件:OnActivating,OnActivated,OnRelease.OnActivating在注册组件使用之前会被调用,此时可以替换实现类或者进行一些其他 ...

  3. vs2017调试源代码

    最近刚入职 ,带我得导师发给我一堆项目,什么云端和医院端,各种wcf服务.window服务和一些公共类库来回调用.搞得是迷迷糊糊,晕头转向.反正是一脸大萌比... 不过经过几个日日夜夜得不停奋战,大致 ...

  4. 【学习笔记】--- 老男孩学Python,day9, 文件操作

    有 + 就是有光标,注意光标位置 不同模式打开文件的完全列表:  http://www.runoob.com/python/python-files-io.html 模式 描述 r 以只读方式打开文件 ...

  5. opencv图像处理时使用stringstream批量读取图片,处理后并保存

    简介: 同文件输入输出流一样,使用stringstream可以批量读取图片,处理后并进行保存.因为C++中头文件 stringstream既可以从string读数据也可向string写数据,利于其这个 ...

  6. Android属性动画简单剖析

    运行效果图: 先看布局文件吧,activity_main.xml: <?xml version="1.0" encoding="utf-8"?> & ...

  7. linux 网络命令last、lastlog、traceroute、netstat

    last /usr/bin/last语法:last功能:列出目前与过去登入系统的用户信息 reboot 是重启信息 lastlog lastlog -u 502(用户ID) traceroute /b ...

  8. Mysql中的delimiter详解

    初学mysql时,可能不太明白delimiter的真正用途,delimiter在mysql很多地方出现,比如存储过程.触发器.函数等. 学过oracle的人,再来学mysql就会感到很奇怪,百思不得其 ...

  9. 树莓派2 raspyberry Pi2 交叉编译app

    Pi 使用的是ARMV7架构的BCM2836, 下载交叉编译器 arm-linux-gnueabihf-gcc 即可. 本地环境: Ubuntu14 + x86_64 1. 下载编译器地址: 1). ...

  10. git添加公钥后报错sign_and_send_pubkey: signing failed: agent refused operation

    在服务器添加完公钥后报错 sign_and_send_pubkey: signing failed: agent refused operation 解决方案: eval "$(ssh-ag ...