1. 程式人生 > >js等比壓縮上傳

js等比壓縮上傳

center actor i++ 接收 ready {} https emf oge

一、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等比壓縮上傳