Skip to content

Commit

Permalink
Added automatic image resizing functionality.
Browse files Browse the repository at this point in the history
Greatly improved the browser responsiveness when loading the preview images.
  • Loading branch information
blueimp committed Feb 11, 2012
1 parent c4a615a commit e39278b
Show file tree
Hide file tree
Showing 8 changed files with 278 additions and 65 deletions.
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,10 @@
Aborted uploads can be resumed with browsers supporting the Blob API.
* **Chunked uploads:**
Large files can be uploaded in smaller chunks with browsers supporting the Blob API.
* **Automatic image resizing:**
Images can be automatically resized with browsers supporting the required JS APIs.
* **Preview images:**
A preview of image files can be displayed before uploading with browsers supporting the required HTML5 APIs.
A preview of image files can be displayed before uploading with browsers supporting the required JS APIs.
* **No browser plugins (e.g. Adobe Flash) required:**
The implementation is based on open standards like HTML5 and JavaScript and requires no additional browser plugins.
* **Graceful fallback for legacy browsers:**
Expand Down
10 changes: 10 additions & 0 deletions css/jquery.fileupload-ui.css
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,16 @@
background: url(../img/progressbar.gif) !important;
filter: none;
}
.fileupload-loading {
position: absolute;
left: 50%;
width: 128px;
height: 0;
background: url(../img/loading.gif) center no-repeat;
}
.fileupload-processing .fileupload-loading {
height: 128px;
}

/* Fix for IE 6: */
*html .fileinput-button {
Expand Down
Binary file added img/loading.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
11 changes: 9 additions & 2 deletions index.html
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<!DOCTYPE HTML>
<!--
/*
* jQuery File Upload Plugin Demo 6.2
* jQuery File Upload Plugin Demo 6.4
* https://github.com/blueimp/jQuery-File-Upload
*
* Copyright 2010, Sebastian Tschan
Expand Down Expand Up @@ -92,6 +92,8 @@ <h1>jQuery File Upload Demo</h1>
</div>
</div>
</div>
<!-- The loading indicator is shown during image processing -->
<div class="fileupload-loading"></div>
<br>
<!-- The table listing the files available for upload/download -->
<table class="table table-striped"><tbody class="files" data-toggle="modal-gallery" data-target="#modal-gallery"></tbody></table>
Expand Down Expand Up @@ -194,16 +196,21 @@ <h3 class="modal-title"></h3>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<!-- The jQuery UI widget factory, can be omitted if jQuery UI is already included -->
<script src="js/vendor/jquery.ui.widget.js"></script>
<!-- The Templates and Load Image plugins are included for the FileUpload user interface -->
<!-- The Templates plugin is included to render the upload/download listings -->
<script src="http://blueimp.github.com/JavaScript-Templates/tmpl.min.js"></script>
<!-- The Load Image plugin is included for the preview images and image resizing functionality -->
<script src="http://blueimp.github.com/JavaScript-Load-Image/load-image.min.js"></script>
<!-- The Canvas to Blob plugin is included for image resizing functionality -->
<script src="http://blueimp.github.com/JavaScript-Canvas-to-Blob/canvas-to-blob.min.js"></script>
<!-- Bootstrap JS and Bootstrap Image Gallery are not required, but included for the demo -->
<script src="http://blueimp.github.com/cdn/js/bootstrap.min.js"></script>
<script src="http://blueimp.github.com/Bootstrap-Image-Gallery/bootstrap-image-gallery.min.js"></script>
<!-- The Iframe Transport is required for browsers without support for XHR file uploads -->
<script src="js/jquery.iframe-transport.js"></script>
<!-- The basic File Upload plugin -->
<script src="js/jquery.fileupload.js"></script>
<!-- The File Upload image processing plugin -->
<script src="js/jquery.fileupload-ip.js"></script>
<!-- The File Upload user interface plugin -->
<script src="js/jquery.fileupload-ui.js"></script>
<!-- The main application script -->
Expand Down
158 changes: 158 additions & 0 deletions js/jquery.fileupload-ip.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
/*
* jQuery File Upload Image Processing Plugin 1.0
* https://github.com/blueimp/jQuery-File-Upload
*
* Copyright 2012, Sebastian Tschan
* https://blueimp.net
*
* Licensed under the MIT license:
* http://www.opensource.org/licenses/MIT
*/

/*jslint nomen: true, unparam: true, regexp: true */
/*global define, window, document */

(function (factory) {
'use strict';
if (typeof define === 'function' && define.amd) {
// Register as an anonymous AMD module:
define([
'jquery',
'./load-image.js',
'./canvas-to-blob.js',
'./jquery.fileupload.js'
], factory);
} else {
// Browser globals:
factory(
window.jQuery,
window.loadImage,
window.canvasToBlob
);
}
}(function ($, loadImage, canvasToBlob) {
'use strict';

// The File Upload IP version extends the basic fileupload widget
// with image processing functionality:
$.widget('blueimpIP.fileupload', $.blueimp.fileupload, {

options: {
// The regular expression to define which image files are to be
// resized, given that the browser supports the operation:
resizeSourceFileTypes: /^image\/(gif|jpeg|png)$/,
// The maximum file size of images that are to be resized:
resizeSourceMaxFileSize: 20000000, // 20MB
// The maximum width of the resized images:
resizeMaxWidth: undefined,
// The maximum height of the resized images:
resizeMaxHeight: undefined,
// The minimum width of the resized images:
resizeMinWidth: undefined,
// The minimum height of the resized images:
resizeMinHeight: undefined,

// The add callback is invoked as soon as files are added to the fileupload
// widget (via file input selection, drag & drop or add API call).
// See the basic file upload widget for more information:
add: function (e, data) {
$(this).fileupload('resize', data).done(function () {
data.submit();
});
}
},

// Resizes the image file at the given index and stores the created blob
// at the original position of the files list, returns a Promise object:
_resizeImage: function (files, index) {
var that = this,
options = this.options,
file = files[index],
deferred = $.Deferred(),
canvas,
blob;
loadImage(
file,
function (img) {
var width = img.width,
height = img.height;
canvas = loadImage.scale(img, {
maxWidth: options.resizeMaxWidth,
maxHeight: options.resizeMaxHeight,
minWidth: options.resizeMinWidth,
minHeight: options.resizeMinHeight,
canvas: true
});
if (width !== canvas.width || height !== canvas.height) {
canvasToBlob(canvas, function (blob) {
if (!blob.name) {
if (file.type === blob.type) {
blob.name = file.name;
} else if (file.name) {
blob.name = file.name.replace(
/\..+$/,
'.' + blob.type.substr(6)
);
}
}
files[index] = blob;
deferred.resolve();
}, file);
} else {
deferred.resolve();
}
}
);
return deferred.promise();
},

// Resizes the images given as files property of the data parameter,
// returns a Promise object that allows to bind a done handler, which
// will be invoked after processing all images is done:
resize: function (data) {
var that = this,
options = $.extend({}, this.options, data),
resizeAll = $.type(options.resizeSourceMaxFileSize) !== 'number';
$.each(data.files, function (index, file) {
if (that._resizeSupport &&
(options.resizeMaxWidth || options.resizeMaxHeight ||
options.resizeMinWidth || options.resizeMinHeight) &&
(resizeAll || file.size < options.resizeSourceMaxFileSize) &&
options.resizeSourceFileTypes.test(file.type)) {
that._processing += 1;
if (that._processing === 1) {
that.element.addClass('fileupload-processing');
}
that._processingQueue = that._processingQueue.pipe(function () {
var deferred = $.Deferred();
that._resizeImage(
data.files,
index
).done(function () {
that._processing -= 1;
if (that._processing === 0) {
that.element
.removeClass('fileupload-processing');
}
deferred.resolve();
});
return deferred.promise();
});
}
});
return this._processingQueue;
},

_create: function () {
$.blueimp.fileupload.prototype._create.call(this);
this._processing = 0;
this._processingQueue = $.Deferred().resolveWith(this).promise();
this._resizeSupport = canvasToBlob(
document.createElement('canvas'),
$.noop
);
}

});

}));
Loading

0 comments on commit e39278b

Please sign in to comment.