-
Notifications
You must be signed in to change notification settings - Fork 22
/
jquery.make-thumb.js
170 lines (155 loc) · 7.55 KB
/
jquery.make-thumb.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
/*
kairyou, 2013-08-01
update: 2015-03-03, Chrome4X/IE11空白; +before/always function; 优化上传效率;
size选项: contain: 等比缩放并拉伸, 图片全部显示; cover: 等比缩放并拉伸, 图片完全覆盖容器; auto 图片不拉伸, 居中显示
fill: 图片小于缩略图尺寸时, 是否填充(false: 缩略图宽高自动缩放到适应图片, true: 缩略图尺寸不变)
stretch: 小图是否强制拉伸以适应缩略图的尺寸(size = auto/contain时)
注意: 添加图片水印不能使用跨域的图片
最好在 http开头的地址 下测试
http://localhost:8080/leon/html5-make-thumb/index.html
*/
(function(window, $, undefined) {
'use strict';
// caches
$.support.filereader = !!(window.File && window.FileReader && window.FileList && window.Blob);
var setting = {
width: 0, // thumbnail width
height: 0, //thumbnail height
fill: false, // fill color when the image is smaller than thumbnails size.
background: '#fff', // fill color
type: 'image/jpeg', // mime-type for thumbnail ('image/jpeg' | 'image/png')
size: 'contain', // CSS3 background-size: contain | cover | auto
mark: {}, // watermark
// text watermark.
// mark = {padding: 5, height: 18, text: 'test', color: '#000', font: '400 18px Arial'} // font: normal, bold, italic
// bgColor: '#ccc' (background color); bgPadding: 5 (padding)
// image watermark. (Note: cross-domain is not allowed)
// mark = {padding: 5, src: 'mark.png', width: 34, height: 45};
stretch: false, // stretch image(small versions) to fill thumbnail (size = auto | contain)
before: null, // call function before process image.
done: null, // success function: call function after thumbnail has been created.
fail: null, // error function
always: null // complete function(done|fail)
};
var $body = $('body');
var IMG_FILE = /image.*/; // var TEXT_FILE = /text.*/;
var dataURItoBlob = function (dataURI, mime) { // convert base64 to raw binary data
var blob;
// BlobBuilder and ArrayBuffer are now deprecated
// github.com/blueimp/JavaScript-Canvas-to-Blob
// stackoverflow.com/q/15639070/2305701
var support = !!($.support.filereader && window.Uint8Array); //|| window.ArrayBuffer, window.FormData
if (!support) return blob;
var arr = dataURI.split(',');
var byteString = atob(arr[1]); // decodeURI(arr[1])
mime = mime || arr[0].split(':')[1].split(';')[0] || 'image/jpeg';
// var ab = new ArrayBuffer(byteString.length);var ia = new Uint8Array(ab); blob = new Blob([ab], { type: mime });
var ia = new Uint8Array(byteString.length);
for (var i = 0; i < byteString.length; i++) {
ia[i] = byteString.charCodeAt(i);
}
// write the ArrayBuffer to a blob, and you're done
blob = new Blob([ia], { type: mime });
return blob;
};
$.fn.makeThumb = function(options) {
var opts = {};
$.extend(opts, setting, options);
var $self = this;
// console.log($self);
// alert(navigator.userAgent);alert(window.FileReader); // android 2.3.7 don't support
if (!$.support.filereader) return;
var size = opts.size;
var before = opts.before,
always = opts.always || opts.complete,
done = opts.done || opts.success,
fail = opts.fail || opts.error;
$self.change(function() {
var self = this;
var files = self.files;
var dataURL = '', blob;
// console.log(files.length);
if ($.isFunction(before)) before();
if (!files.length) {
if ($.isFunction(fail)) fail.apply(self, []);
if ($.isFunction(always)) always();
return;
}
var file = files[0];
var fr = new FileReader();
// console.log('fileInfo:', file);
// creat <canvas>
var $canvas = $('<canvas></canvas>'),
canvas = $canvas[0],
context = canvas.getContext('2d');
var image, fEvt;
var imageSize, targetSize;
var targetH, targetW, tragetX, tragetY;
var ratio;
var callback = function() {
// $canvas.appendTo($body).hide();
dataURL = canvas.toDataURL(opts.type); // 'image/jpeg'
blob = dataURItoBlob(dataURL);
// debug: show thumb
// var thumb = new Image();thumb.src = dataURL;$(thumb).appendTo($body);
if ($.isFunction(done)) {
targetSize = {width: targetW, height: targetH};
done.apply(self, [dataURL, blob, targetSize, file, imageSize, fEvt]);
}
if ($.isFunction(always)) always();
$canvas.remove(); // delete canvas
};
var mpImg = new MegaPixImage(file);
mpImg.onrender = function() {
callback();
}
var drawImage = function(exif) {
var orientation = exif.Orientation;
canvas.width = opts.width;
canvas.height = opts.height;
// use mpImg
if (opts.background) {
context.fillStyle = opts.background;
context.fillRect(0, 0, opts.width, opts.height);
}
mpImg.render(canvas, { maxWidth: opts.width, maxHeight: opts.height, orientation: orientation });
};
if (IMG_FILE.test(file.type)) {
// console.log('file.name:', file.name);
fr.onerror = function(fEvent) { // error callback
fEvt = fEvent;
if ($.isFunction(fail)) fail.apply(self, [file, fEvt]);
if ($.isFunction(always)) always();
};
fr.onload = function(fEvent) { // onload success
fEvt = fEvent;
// console.log(fEvt);
var target = fEvt.target;
var result = target.result;
// load img
image = new Image();
var exif;
image.onerror = function(){
if ($.isFunction(fail)) fail.apply(self, [file]);
if ($.isFunction(always)) always();
};
image.onload = function() { // imgW / height
drawImage.apply(null, [exif]);
};
// Converting the data-url to a binary string
var base64 = result.replace(/^.*?,/,'');
var binary = atob(base64);
var binaryData = new BinaryFile(binary);
// get EXIF data
exif = EXIF.readFromBinaryFile(binaryData);
// console.log(exif);
// console.log(file.name +': '+ exif.Orientation);
image.src = result;
};
fr.readAsDataURL(file);
// 用fr.readAsBinaryString(file); 也要用binaryajax(exif对binaryajax的方法有依赖), 而且返回的图片是空白
// 猜测是没有用image.onload里面去drawImage导致.
}
});
};
})(window, jQuery);