2013-10-03 61 views
0

我正在使用fileupload jQuery插件上傳文件到我的網站。我想在上傳之前調整圖像大小以儘量減少網絡使用量,但目前我找不到完整的示例。這是我的簡單測試代碼。客戶端調整大小與JQuery文件上傳

<script src="//ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script> 
<script src="/static/js/cloudinary/jquery.ui.widget.js" type="text/javascript"></script> 
<script src="/static/js/cloudinary/load-image.min.js" type="text/javascript"></script> 
<script src="/static/js/cloudinary/canvas-to-blob.min.js" type="text/javascript"></script> 
<script src="/static/js/cloudinary/jquery.iframe-transport.js" type="text/javascript"></script> 
<script src="/static/js/cloudinary/jquery.fileupload.js" type="text/javascript"></script> 
<script src="/static/js/cloudinary/jquery.fileupload-ip.js" type="text/javascript"></script> 
<script src="/static/js/cloudinary/jquery.fileupload-process.js" type="text/javascript"></script> 
<script src="/static/js/cloudinary/jquery.fileupload-validate.js" type="text/javascript"></script> 

... 

$("#fileupload") 
    .fileupload({ 
     disableImageResize: false, 
     imageMaxWidth: 8000, 
     imageMaxHeight: 6000, 
     acceptFileTypes: /(\.|\/)(gif|jpe?g|png|bmp|ico)$/i, 
     maxFileSize: 20000000, // 20MB 
     process: [ 
      { 
       action: 'load', 
       fileTypes: /^image\/(gif|jpeg|png)$/, 
       maxFileSize: 20000000 // 20MB 
      }, 
      { 
       action: 'resize', 
       maxWidth: 200, 
       maxHeight: 150, 
       minWidth: 80, 
       minHeight: 60 
      }, 
      { 
       action: 'save' 
      } 
     ] 

    }); 

回答

0

我有一個類似的問題,我相信是由於沒有canvas-to-blob.js。添加該腳本,讓它工作。我正在使用鉻。在Github上查看此問題:

https://github.com/blueimp/jQuery-File-Upload/issues/2665

而且,你可能不需要任何描述整個處理流水線描述,因爲它基於特定參數的存在jQuery的文件上傳建立必要階段。

0

因爲把所有的部分放在一起爲一個複雜的上傳器工作是一項複雜的任務,我在這裏分享我的解決方案。

這個答案

  • 的元素可以有每頁上傳的任意數量。在這個例子中,頁面上有兩個單獨的上傳按鈕,稱爲驅動醫療

  • 上傳過程中爲用戶上傳上傳圖像的

  • 顯示預覽

  • HTML代碼神社2個模板

  • 前更改圖像1024的客戶端×1024

    Bootstrap 3.x主題上傳按鈕和上傳進度條

  • 金字塔樣式JavaScript資源加載

    這使得一個單獨的上載插件(upload_snippet.html

金賈2 HTML模板代碼,它需要參數ID名稱upload_target

<div id="upload-{{ id }}"> 

    <div id="medical-license" class="btn btn-block btn-file"> 
     <i class="fa fa-camera"></i> {{ name }} 

     <input type="file" class="file-select" data-url="{{ upload_target }}" data-param-name="{{ id }}"> 
    </div> 
    <p> 
     <div class="preview" style="display: none"></div> 
    </p> 

    <div class="progress progress-xxx" style="display: none"> 
     <div class="progress-bar progress-bar-striped progress-bar-xxx active" role="progressbar" aria-valuenow="45" aria-valuemin="0" aria-valuemax="100" style="width: 0%"> 
     </div> 
    </div> 

    <div class="success" style="display: none"> 

     <div class="alert alert-success"> 
      {{ name }} upload completed 
     </div> 
    </div> 

    <div class="error" style="display: none"> 

     <div class="alert alert-danger"> 
      <span class="error-message"></span> 
     </div> 
    </div> 
</div> 

主要金賈2HTML模板,其構造兩個上傳小部件。它的風格它們看起來像引導按鈕:

{% extends "site/base.html" %} 

{% block extra_head %} 
    <style> 
    /* http://www.abeautifulsite.net/whipping-file-inputs-into-shape-with-bootstrap-3/ */ 
    .btn-file { 
     position: relative; 
     overflow: hidden; 
    } 
    .btn-file input[type=file] { 
     position: absolute; 
     top: 0; 
     right: 0; 
     min-width: 100%; 
     min-height: 100%; 
     font-size: 100px; 
     text-align: right; 
     filter: alpha(opacity=0); 
     opacity: 0; 
     outline: none; 
     background: white; 
     cursor: inherit; 
     display: block; 
    } 

    .preview { 
     width: 128px; 
     height: 128px; 
     margin: 0 auto; 
    } 
    </style> 
{% endblock %} 

{% block content_section %} 
    <!-- Header --> 
    <section id="license-information"> 

     <div class="row"> 
      <div class="col-md-12"> 
       <h1>Upload information</h1> 
      </div> 
     </div> 

     <div class="row"> 
      <div class="col-md-6"> 

       {% with id='medical', name='Medical license' %} 
        {% include "upload_snippet.html" %} 
       {% endwith %} 

       {% with id='driving', name='Driving license or other id' %} 
        {% include "upload_snippet.html" %} 
       {% endwith %} 


      </div> 
     </div> 

    </section> 
{% endblock content_section %} 

{% block custom_script %} 

<!-- The jQuery UI widget factory, can be omitted if jQuery UI is already included --> 
<script src="{{ 'xxx:static/jquery-file-upload/js/vendor/jquery.ui.widget.js'| static_url }}"></script> 

<!-- The Load Image plugin is included for the preview images and image resizing functionality --> 
<script src="{{ 'xxx:static/jquery-file-upload/js/load-image.all.min.js' | static_url }}"></script> 

<!-- The Canvas to Blob plugin is included for image resizing functionality --> 
<script src="{{ 'xxx:static/jquery-file-upload/js/canvas-to-blob.js' | static_url }}"></script> 

<!-- The basic File Upload plugin --> 
<script src="{{ 'xxx:static/jquery-file-upload/js/jquery.fileupload.js' | static_url }}"></script> 
<!-- The File Upload processing plugin --> 
<script src="{{ 'xxx:static/jquery-file-upload/js/jquery.fileupload-process.js' | static_url }} "></script> 
<!-- The File Upload image preview & resize plugin --> 
<script src="{{ 'xxx:static/jquery-file-upload/js/jquery.fileupload-image.js' | static_url }} "></script> 

<script> 
window.nextURL = "{{ after_both_files_are_uploaded }}" 
</script> 

<script> 
    "use strict"; 

    var state = { 
     medical: false, 
     driving: false 
    } 

    // Make styled elements to trigger file input 
    $(document).on('change', '.btn-file :file', function() { 
     var input = $(this), 
      numFiles = input.get(0).files ? input.get(0).files.length : 1, 
      label = input.val().replace(/\\/g, '/').replace(/.*\//, ''); 
     input.trigger('fileselect', [numFiles, label]); 
    }); 

    function checkForward() { 
     // Is all upload done and we can go to the next page? 
     if(state.medical && state.driving) { 
      window.location = window.nextURL; 
     } 
    } 

    function doUpload(name) { 

     var baseElem = $("#upload-" + name); 

     if(baseElem.length != 1) { 
      throw new Error("Wooops, bad DOM tree"); 
     } 

     function onStart() { 
      baseElem.find(".progress").show(); 
      baseElem.find(".error").hide(); 
      baseElem.find(".success").hide(); 
     } 

     function onDone(result, data) { 
      baseElem.find(".progress").hide(); 
      if(data.result.status == "ok") { 
       // All ok, check if we can proceed 
       baseElem.find(".success").show(); 
       state[name] = true; 
       checkForward(); 
      } else { 
       // Server responded us it didn't like the file and gave a specific error message 
       var msg = data.result.message; 
       baseElem.find(".error-message").text(msg); 
       baseElem.find(".error").show(); 
       state[name] = false; 
      } 
     } 

     function onError(result, data) { 
      baseElem.find(".progress").hide(); 
      baseElem.find(".error-message").text("Upload could not be completed. Please contact the support."); 
      baseElem.find(".error").show(); 
      state[name] = false; 
     } 

     function onProgress(e, data) { 
      var progress = parseInt(data.loaded/data.total * 100, 10); 
      baseElem.find(".progress-bar").css("width", progress + "%"); 
     } 

     function onPreview(e, data) { 
      var canvas = data.files[0].preview; 
      var dataURL = canvas.toDataURL(); 
      baseElem.find(".preview").css("background-image", 'url(' + dataURL +')'); 
      baseElem.find(".preview").css({width: canvas.width, height: canvas.height}); 
      baseElem.find(".preview").show(); 
     } 

     var upload = baseElem.find('.file-select'); 
     upload.fileupload({ 
      dataType: 'json', 
      // Enable image resizing, except for Android and Opera, 
      // which actually support image resizing, but fail to 
      // send Blob objects via XHR requests: 
      // disableImageResize: /Android(?!.*Chrome)|Opera/ 
      // .test(window.navigator && navigator.userAgent), 
      disableImageResize: false, 
      imageMaxWidth: 1024, 
      imageMaxHeight: 1024, 
      imageCrop: false, // Force cropped images, 
      previewMaxWidth: 128, 
      previewMaxHeight: 128, 
      maxFileSize: 7*1024*1024 
     }); 

     upload.bind("fileuploaddone", onDone); 
     upload.bind("fileuploadstart", onStart); 
     upload.bind("fileuploadfail", onError); 
     upload.bind("fileuploadprogress", onProgress); 
     upload.bind('fileuploadprocessalways', onPreview); 

    } 

    $(document).ready(function() { 
     doUpload("medical"); 
     doUpload("driving"); 
    }); 
</script> 

{% endblock %} 

然後進行解碼的有效載荷和檢查一個簡單的服務器端金字塔視圖,用戶上傳的圖像,而不是一個隨機文件。結果是JavaScript可以解碼的JSON響應:

@view_config(route_name='upload_target', renderer='json') 
def upload_target(request): 
    """AJAX upload of driving license and medical images.""" 
    if "medical" in request.params: 
     license = "medical" 
     files = request.params["medical"] 
    elif "driving" in request.params: 
     license = "driving" 
     files = request.params["driving"] 
    else: 
     raise RuntimeError("Unsupported upload type") 

    # # TODO: use chunks, do not buffer 100% 
    # path = user.prepare_upload_path() 
    storage = io.open(where_to_save, "wb") 
    fp = files.file 

    # Now we test for a valid image upload 
    image_test = imghdr.what(fp) 
    if image_test == None: 
     return {"status": "fail", "message": "Only JPEG and PNG image file upload supported."} 

    fp.seek(0) 
    data = fp.read() 
    assert len(data) > 0 
    storage.write(data) 
    storage.close() 

    return {"status": "ok"} 
相關問題