|
1 |
var ExifRestorer = (function()
|
|
2 |
{
|
|
3 |
// from http://www.perry.cz/files/ExifRestorer.js
|
|
4 |
// based on MinifyJpeg
|
|
5 |
// http://elicon.blog57.fc2.com/blog-entry-206.html
|
|
6 |
|
|
7 |
var ExifRestorer = {};
|
|
8 |
|
|
9 |
ExifRestorer.KEY_STR = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
|
|
10 |
|
|
11 |
ExifRestorer.encode64 = function(input)
|
|
12 |
{
|
|
13 |
var output = "",
|
|
14 |
chr1, chr2, chr3 = "",
|
|
15 |
enc1, enc2, enc3, enc4 = "",
|
|
16 |
i = 0;
|
|
17 |
|
|
18 |
do {
|
|
19 |
chr1 = input[i++];
|
|
20 |
chr2 = input[i++];
|
|
21 |
chr3 = input[i++];
|
|
22 |
|
|
23 |
enc1 = chr1 >> 2;
|
|
24 |
enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
|
|
25 |
enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
|
|
26 |
enc4 = chr3 & 63;
|
|
27 |
|
|
28 |
if (isNaN(chr2)) {
|
|
29 |
enc3 = enc4 = 64;
|
|
30 |
} else if (isNaN(chr3)) {
|
|
31 |
enc4 = 64;
|
|
32 |
}
|
|
33 |
|
|
34 |
output = output +
|
|
35 |
this.KEY_STR.charAt(enc1) +
|
|
36 |
this.KEY_STR.charAt(enc2) +
|
|
37 |
this.KEY_STR.charAt(enc3) +
|
|
38 |
this.KEY_STR.charAt(enc4);
|
|
39 |
chr1 = chr2 = chr3 = "";
|
|
40 |
enc1 = enc2 = enc3 = enc4 = "";
|
|
41 |
} while (i < input.length);
|
|
42 |
|
|
43 |
return output;
|
|
44 |
};
|
|
45 |
|
|
46 |
ExifRestorer.restore = function(origFileBase64, resizedFileBase64)
|
|
47 |
{
|
|
48 |
if (!origFileBase64.match("data:image/jpeg;base64,"))
|
|
49 |
{
|
|
50 |
return resizedFileBase64;
|
|
51 |
}
|
|
52 |
|
|
53 |
var rawImage = this.decode64(origFileBase64.replace("data:image/jpeg;base64,", ""));
|
|
54 |
var segments = this.slice2Segments(rawImage);
|
|
55 |
|
|
56 |
var image = this.exifManipulation(resizedFileBase64, segments);
|
|
57 |
|
|
58 |
return this.encode64(image);
|
|
59 |
};
|
|
60 |
|
|
61 |
ExifRestorer.restore_as_blob = function(origFileBase64, resizedFileBase64) {
|
|
62 |
var b64Data = ExifRestorer.restore(origFileBase64, resizedFileBase64);
|
|
63 |
contentType = 'image/jpeg';
|
|
64 |
sliceSize = 512;
|
|
65 |
|
|
66 |
var byteCharacters = atob(b64Data);
|
|
67 |
var byteArrays = [];
|
|
68 |
|
|
69 |
for (var offset = 0; offset < byteCharacters.length; offset += sliceSize) {
|
|
70 |
var slice = byteCharacters.slice(offset, offset + sliceSize);
|
|
71 |
var byteNumbers = new Array(slice.length);
|
|
72 |
for (var i = 0; i < slice.length; i++) {
|
|
73 |
byteNumbers[i] = slice.charCodeAt(i);
|
|
74 |
}
|
|
75 |
var byteArray = new Uint8Array(byteNumbers);
|
|
76 |
byteArrays.push(byteArray);
|
|
77 |
}
|
|
78 |
return new Blob(byteArrays, {type: contentType});
|
|
79 |
};
|
|
80 |
|
|
81 |
ExifRestorer.exifManipulation = function(resizedFileBase64, segments)
|
|
82 |
{
|
|
83 |
var exifArray = this.getExifArray(segments),
|
|
84 |
newImageArray = this.insertExif(resizedFileBase64, exifArray),
|
|
85 |
aBuffer = new Uint8Array(newImageArray);
|
|
86 |
|
|
87 |
return aBuffer;
|
|
88 |
};
|
|
89 |
|
|
90 |
ExifRestorer.getExifArray = function(segments)
|
|
91 |
{
|
|
92 |
var seg;
|
|
93 |
for (var x = 0; x < segments.length; x++)
|
|
94 |
{
|
|
95 |
seg = segments[x];
|
|
96 |
if (seg[0] == 255 & seg[1] == 225) //(ff e1)
|
|
97 |
{
|
|
98 |
return seg;
|
|
99 |
}
|
|
100 |
}
|
|
101 |
return [];
|
|
102 |
};
|
|
103 |
|
|
104 |
ExifRestorer.insertExif = function(resizedFileBase64, exifArray)
|
|
105 |
{
|
|
106 |
var imageData = resizedFileBase64.replace("data:image/jpeg;base64,", ""),
|
|
107 |
buf = this.decode64(imageData),
|
|
108 |
separatePoint = buf.indexOf(255,3),
|
|
109 |
mae = buf.slice(0, separatePoint),
|
|
110 |
ato = buf.slice(separatePoint),
|
|
111 |
array = mae;
|
|
112 |
|
|
113 |
array = array.concat(exifArray);
|
|
114 |
array = array.concat(ato);
|
|
115 |
return array;
|
|
116 |
};
|
|
117 |
|
|
118 |
|
|
119 |
ExifRestorer.slice2Segments = function(rawImageArray)
|
|
120 |
{
|
|
121 |
var head = 0,
|
|
122 |
segments = [];
|
|
123 |
|
|
124 |
while (1)
|
|
125 |
{
|
|
126 |
if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 218){break;}
|
|
127 |
if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 216)
|
|
128 |
{
|
|
129 |
head += 2;
|
|
130 |
}
|
|
131 |
else
|
|
132 |
{
|
|
133 |
var length = rawImageArray[head + 2] * 256 + rawImageArray[head + 3],
|
|
134 |
endPoint = head + length + 2,
|
|
135 |
seg = rawImageArray.slice(head, endPoint);
|
|
136 |
segments.push(seg);
|
|
137 |
head = endPoint;
|
|
138 |
}
|
|
139 |
if (head > rawImageArray.length){break;}
|
|
140 |
}
|
|
141 |
|
|
142 |
return segments;
|
|
143 |
};
|
|
144 |
|
|
145 |
ExifRestorer.decode64 = function(input)
|
|
146 |
{
|
|
147 |
var output = "",
|
|
148 |
chr1, chr2, chr3 = "",
|
|
149 |
enc1, enc2, enc3, enc4 = "",
|
|
150 |
i = 0,
|
|
151 |
buf = [];
|
|
152 |
|
|
153 |
// remove all characters that are not A-Z, a-z, 0-9, +, /, or =
|
|
154 |
var base64test = /[^A-Za-z0-9\+\/\=]/g;
|
|
155 |
if (base64test.exec(input)) {
|
|
156 |
alert("There were invalid base64 characters in the input text.\n" +
|
|
157 |
"Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='\n" +
|
|
158 |
"Expect errors in decoding.");
|
|
159 |
}
|
|
160 |
input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");
|
|
161 |
|
|
162 |
do {
|
|
163 |
enc1 = this.KEY_STR.indexOf(input.charAt(i++));
|
|
164 |
enc2 = this.KEY_STR.indexOf(input.charAt(i++));
|
|
165 |
enc3 = this.KEY_STR.indexOf(input.charAt(i++));
|
|
166 |
enc4 = this.KEY_STR.indexOf(input.charAt(i++));
|
|
167 |
|
|
168 |
chr1 = (enc1 << 2) | (enc2 >> 4);
|
|
169 |
chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
|
|
170 |
chr3 = ((enc3 & 3) << 6) | enc4;
|
|
171 |
|
|
172 |
buf.push(chr1);
|
|
173 |
|
|
174 |
if (enc3 != 64) {
|
|
175 |
buf.push(chr2);
|
|
176 |
}
|
|
177 |
if (enc4 != 64) {
|
|
178 |
buf.push(chr3);
|
|
179 |
}
|
|
180 |
|
|
181 |
chr1 = chr2 = chr3 = "";
|
|
182 |
enc1 = enc2 = enc3 = enc4 = "";
|
|
183 |
|
|
184 |
} while (i < input.length);
|
|
185 |
|
|
186 |
return buf;
|
|
187 |
};
|
|
188 |
|
|
189 |
return ExifRestorer;
|
|
190 |
})();
|
|
191 |
|
1 |
192 |
$.WcsFileUpload = {
|
2 |
193 |
prepare: function() {
|
3 |
194 |
var base_widget = $(this);
|
|
195 |
var image_resize = $(this).find('.file-button').data('image-resize');
|
|
196 |
if (typeof(FileReader) === "undefined") {
|
|
197 |
image_resize = false;
|
|
198 |
}
|
4 |
199 |
if ($(base_widget).find('input[type=hidden]').val()) {
|
5 |
200 |
$(base_widget).find('input[type=file]').hide();
|
6 |
201 |
$(base_widget).find('.use-file-from-fargo').hide();
|
... | ... | |
14 |
209 |
pasteZone: base_widget,
|
15 |
210 |
dataType: 'json',
|
16 |
211 |
add: function (e, data) {
|
17 |
|
$(base_widget).find('.fileprogress').removeClass('upload-error');
|
18 |
|
$(base_widget).find('.fileprogress .bar').text(
|
19 |
|
$(base_widget).find('.fileprogress .bar').data('upload'));
|
20 |
|
$(base_widget).find('.fileprogress .bar').css('width', '0%');
|
21 |
|
$(base_widget).find('.fileprogress').show();
|
22 |
|
$(base_widget).find('.fileinfo').hide();
|
23 |
|
$(base_widget).parents('form').find('input[name=submit]').prop('disabled', true);
|
24 |
|
var jqXHR = data.submit();
|
|
212 |
if (image_resize && (
|
|
213 |
data.files[0].type == 'image/jpeg' ||
|
|
214 |
data.files[0].type == 'image/png')) {
|
|
215 |
|
|
216 |
$(base_widget).find('.fileprogress .bar').css('width', '100%');
|
|
217 |
$(base_widget).find('.fileprogress .bar').text(
|
|
218 |
$(base_widget).find('.fileprogress .bar').data('resize'));
|
|
219 |
$(base_widget).find('.fileprogress').show();
|
|
220 |
|
|
221 |
var reader = new FileReader();
|
|
222 |
reader.onload = function(e) {
|
|
223 |
var original_image_64 = e.target.result;
|
|
224 |
var img = document.createElement("img");
|
|
225 |
img.onload = function() {
|
|
226 |
var canvas = document.createElement("canvas");
|
|
227 |
var ctx = canvas.getContext('2d');
|
|
228 |
ctx.drawImage(img, 0, 0);
|
|
229 |
|
|
230 |
var MAX_WIDTH = 2000;
|
|
231 |
var MAX_HEIGHT = 2000;
|
|
232 |
var width = img.width;
|
|
233 |
var height = img.height;
|
|
234 |
|
|
235 |
if (width > height) {
|
|
236 |
if (width > MAX_WIDTH) {
|
|
237 |
height *= MAX_WIDTH / width;
|
|
238 |
width = MAX_WIDTH;
|
|
239 |
}
|
|
240 |
} else {
|
|
241 |
if (height > MAX_HEIGHT) {
|
|
242 |
width *= MAX_HEIGHT / height;
|
|
243 |
height = MAX_HEIGHT;
|
|
244 |
}
|
|
245 |
}
|
|
246 |
canvas.width = width;
|
|
247 |
canvas.height = height;
|
|
248 |
var ctx = canvas.getContext('2d');
|
|
249 |
ctx.drawImage(img, 0, 0, width, height);
|
|
250 |
var new_image_64 = canvas.toDataURL('image/jpeg', 0.95);
|
|
251 |
var blob = ExifRestorer.restore_as_blob(original_image_64, new_image_64);
|
|
252 |
blob.name = data.files[0].name;
|
|
253 |
data.files[0] = blob;
|
|
254 |
return $.WcsFileUpload.upload(base_widget, data);
|
|
255 |
}
|
|
256 |
img.src = e.target.result;
|
|
257 |
}
|
|
258 |
reader.readAsDataURL(data.files[0]);
|
|
259 |
} else {
|
|
260 |
return $.WcsFileUpload.upload(base_widget, data);
|
|
261 |
}
|
25 |
262 |
},
|
26 |
263 |
done: function(e, data) {
|
27 |
264 |
$(base_widget).find('.fileprogress').hide();
|
... | ... | |
57 |
294 |
$(base_widget).find('input[type=file]').click();
|
58 |
295 |
return false;
|
59 |
296 |
});
|
|
297 |
},
|
|
298 |
|
|
299 |
upload: function(base_widget, data) {
|
|
300 |
$(base_widget).find('.fileprogress').removeClass('upload-error');
|
|
301 |
$(base_widget).find('.fileprogress .bar').text(
|
|
302 |
$(base_widget).find('.fileprogress .bar').data('upload'));
|
|
303 |
$(base_widget).find('.fileprogress .bar').css('width', '0%');
|
|
304 |
$(base_widget).find('.fileprogress').show();
|
|
305 |
$(base_widget).find('.fileinfo').hide();
|
|
306 |
$(base_widget).parents('form').find('input[name=submit]').prop('disabled', true);
|
|
307 |
var jqXHR = data.submit();
|
60 |
308 |
}
|
|
309 |
|
61 |
310 |
}
|
62 |
311 |
|
63 |
312 |
$(function() {
|