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方法 ...
随机推荐
- 数据库导出Excel(转载)
来源:https://jingyan.baidu.com/article/3065b3b68f2ab7becef8a449.html SQLServer2005或者SQLServer2008.SQLS ...
- C# 的逻辑运算
&.^.!和|操作符称为逻辑操作符,用逻辑操作符把运算对象连接起来符合C#语法的式子称为逻辑表达式.逻辑 操作符“!”和“^”只作用于其后的操作数,故称为一元操作符.而“&&” ...
- PHP 错误解决锦集
Part1:Maximum execution time of 120 seconds exceeded 120秒运行超时的错误 解决办法: 方法一,修改php.ini文件 max_execution ...
- K:图的存储结构
常用的图的存储结构主要有两种,一种是采用数组链表(邻接表)的方式,一种是采用邻接矩阵的方式.当然,图也可以采用十字链表或者边集数组的方式来进行表示,但由于不常用,为此,本博文不对其进行介绍. 邻接 ...
- QT的信号和槽机制简介
信号与槽作为QT的核心机制在QT编程中有着广泛的应用,本文介绍了信号与槽的一些基本概念.元对象工具以及在实际使用过程中应注意的一些问题. QT是一个跨平台的C++ GUI应用构架,它提供了丰富的窗口部 ...
- CentOS 7 yum安装配置mysql
首先去官网下载要用的yum源 传送门:http://dev.mysql.com/downloads/repo/yum/ yum源文件:/home/mysql57-community-release-e ...
- ACK-Ackermann, 阿克曼函数
以前好几次在学语言的使用都有实现这个ack函数的经历,今天读本算法书,偶尔又提到了这个,查了下wiki来头好大 Values of A(m, n) m\n 0 1 2 3 4 n 0 1 2 3 4 ...
- 虚拟主机服务器php fsockopen函数被禁用的解决方法
为了服务器安全考虑很多主机商禁用了php的fsockopen函数,昨天进博客,使用cos-html-cache生成静态文件,尼玛提示: Warning: fsockopen() has been di ...
- Jquery插件网站持续添加。。。
Look Fro Less,Do More www.jq22.com
- Pig安装与应用
1. 参考说明 参考文档: http://pig.apache.org/docs/r0.17.0/start.html#build 2. 安装环境说明 2.1. 环境说明 CentOS7.4+ ...