客户端通过JQuery fileupload调整大小

问题描述 投票:0回答:3

我正在使用fileupload 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'
            }
        ]

    });
jquery jquery-file-upload
3个回答
0
投票

我有一个类似的问题,我相信是由于缺少canvas-to-blob.js。添加该脚本,使其工作。我正在使用Chrome。在github上看到这个问题:

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

[另外,您可能也不需要描述整个处理管道的描述,因为jquery文件上传会根据某些参数的存在建立必要的阶段。


0
投票

由于将所有内容组合在一起为一个复杂的上传器工作是一项复杂的任务,因此我在这里分享我的解决方案。

此答案的要素

  • 每页可以有任意数量的上传者。在此示例中,页面上有两个单独的上传按钮,分别称为drivingmedical

  • 在上传之前将图像在客户端调整为1024 x 1024

  • [在上传过程中为用户显示上传图像的预览

  • HTML代码为Jinja 2模板

  • Bootstrap 3.x主题上载按钮和上载进度条

  • 金字塔样式JavaScript资源加载

Jinja 2 HTML模板代码,呈现一个单独的上载小部件(upload_snippet.html),它接受参数idnameupload_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>

主要的Jinja 2HTML模板构造了两个上传小部件。样式使它们看起来像Bootstrap按钮:

{% 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"}

0
投票

jQuery拖放文件上传| Bootstrap映像上传和预览

// Code By Webdevtrick ( https://webdevtrick.com )
function readFile(input) {
  if (input.files && input.files[0]) {
    var reader = new FileReader();

    reader.onload = function(e) {
      var htmlPreview =
        '<img width="200" src="' + e.target.result + '" />' +
        '<p>' + input.files[0].name + '</p>';
      var wrapperZone = $(input).parent();
      var previewZone = $(input).parent().parent().find('.preview-zone');
      var boxZone = $(input).parent().parent().find('.preview-zone').find('.box').find('.box-body');

      wrapperZone.removeClass('dragover');
      previewZone.removeClass('hidden');
      boxZone.empty();
      boxZone.append(htmlPreview);
    };

    reader.readAsDataURL(input.files[0]);
  }
}

function reset(e) {
  e.wrap('<form>').closest('form').get(0).reset();
  e.unwrap();
}

$(".dropzone").change(function() {
  readFile(this);
});

$('.dropzone-wrapper').on('dragover', function(e) {
  e.preventDefault();
  e.stopPropagation();
  $(this).addClass('dragover');
});

$('.dropzone-wrapper').on('dragleave', function(e) {
  e.preventDefault();
  e.stopPropagation();
  $(this).removeClass('dragover');
});

$('.remove-preview').on('click', function() {
  var boxZone = $(this).parents('.preview-zone').find('.box-body');
  var previewZone = $(this).parents('.preview-zone');
  var dropzone = $(this).parents('.form-group').find('.dropzone');
  boxZone.empty();
  previewZone.addClass('hidden');
  reset(dropzone);
});
/* Code By Webdevtrick ( https://webdevtrick.com ) */
.container {
  padding: 50px 10%;
}

.box {
  position: relative;
  background: #ffffff;
  width: 100%;
}

.box-header {
  color: #444;
  display: block;
  padding: 10px;
  position: relative;
  border-bottom: 1px solid #f4f4f4;
  margin-bottom: 10px;
}

.box-tools {
  position: absolute;
  right: 10px;
  top: 5px;
}

.dropzone-wrapper {
  border: 2px dashed #91b0b3;
  color: #92b0b3;
  position: relative;
  height: 150px;
}

.dropzone-desc {
  position: absolute;
  margin: 0 auto;
  left: 0;
  right: 0;
  text-align: center;
  width: 40%;
  top: 50px;
  font-size: 16px;
}

.dropzone,
.dropzone:focus {
  position: absolute;
  outline: none !important;
  width: 100%;
  height: 150px;
  cursor: pointer;
  opacity: 0;
}

.dropzone-wrapper:hover,
.dropzone-wrapper.dragover {
  background: #ecf0f5;
}

.preview-zone {
  text-align: center;
}

.preview-zone .box {
  box-shadow: none;
  border-radius: 0;
  margin-bottom: 0;
}

.btn-primary {
  background-color: crimson;
  border: 1px solid #212121;
}
<!DOCTYPE html>
<!-- Code By Webdevtrick ( https://webdevtrick.com ) -->
<html lang="en" >
<head>
  <meta charset="UTF-8">
  <title>Drag and Drop Image Upload | Webdevtrick.com</title>
  <link rel='stylesheet' href='https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap.min.css'>
  <link rel="stylesheet" href="style.css">

</head>
<body>

<section>
  <form action="" method="POST" enctype="multipart/form-data">
    <div class="container">
      <div class="row">
        <div class="col-md-12">
          <div class="form-group">
            <label class="control-label">Upload File</label>
            <div class="preview-zone hidden">
              <div class="box box-solid">
                <div class="box-header with-border">
                  <div><b>Preview</b></div>
                  <div class="box-tools pull-right">
                    <button type="button" class="btn btn-danger btn-xs remove-preview">
                      <i class="fa fa-times"></i> Reset The Field
                    </button>
                  </div>
                </div>
                <div class="box-body"></div>
              </div>
            </div>
            <div class="dropzone-wrapper">
              <div class="dropzone-desc">
                <i class="glyphicon glyphicon-download-alt"></i>
                <p>Choose an image file or drag it here.</p>
              </div>
              <input type="file" name="img_logo" class="dropzone">
            </div>
          </div>
        </div>
      </div>

      <div class="row">
        <div class="col-md-12">
          <button type="submit" class="btn btn-primary pull-right">Upload</button>
        </div>
      </div>
    </div>
  </form>
</section>


<script src='https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js'></script>
<script src='https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/js/bootstrap.min.js'></script>
<script  src="function.js"></script>

</body>
</html>
© www.soinside.com 2019 - 2024. All rights reserved.