Dotclear

source: admin/js/jsUpload/load-image.js @ 1144:4af82896ca3d

Revision 1144:4af82896ca3d, 12.5 KB checked in by Nicolas <nikrou77@…>, 12 years ago (diff)

Remplacement de l'upload utilisant swfupload par le plugin jQuery-File-Upload

Todo:

  • Gestion des suppressions
  • Gestion des annulations
  • Gestion des mises de l'interface sans rechargement de la page
  • Simplification (moins de javascript) ?
Line 
1/*
2 * JavaScript Load Image 1.6
3 * https://github.com/blueimp/JavaScript-Load-Image
4 *
5 * Copyright 2011, Sebastian Tschan
6 * https://blueimp.net
7 *
8 * iOS image scaling fixes based on
9 * https://github.com/stomita/ios-imagefile-megapixel
10 *
11 * Licensed under the MIT license:
12 * http://www.opensource.org/licenses/MIT
13 */
14
15/*jslint nomen: true, bitwise: true */
16/*global window, document, URL, webkitURL, Blob, File, FileReader, define */
17
18(function ($) {
19    'use strict';
20
21    // Loads an image for a given File object.
22    // Invokes the callback with an img or optional canvas
23    // element (if supported by the browser) as parameter:
24    var loadImage = function (file, callback, options) {
25            var img = document.createElement('img'),
26                url,
27                oUrl;
28            img.onerror = callback;
29            img.onload = function () {
30                if (oUrl && !(options && options.noRevoke)) {
31                    loadImage.revokeObjectURL(oUrl);
32                }
33                if (callback) {
34                    callback(loadImage.scale(img, options));
35                }
36            };
37            if (loadImage.isInstanceOf('Blob', file) ||
38                    // Files are also Blob instances, but some browsers
39                    // (Firefox 3.6) support the File API but not Blobs:
40                    loadImage.isInstanceOf('File', file)) {
41                url = oUrl = loadImage.createObjectURL(file);
42                // Store the file type for resize processing:
43                img._type = file.type;
44            } else if (typeof file === 'string') {
45                url = file;
46                if (options && options.crossOrigin) {
47                    img.crossOrigin = options.crossOrigin;
48                }
49            } else {
50                return false;
51            }
52            if (url) {
53                img.src = url;
54                return img;
55            }
56            return loadImage.readFile(file, function (e) {
57                var target = e.target;
58                if (target && target.result) {
59                    img.src = target.result;
60                } else {
61                    if (callback) {
62                        callback(e);
63                    }
64                }
65            });
66        },
67        // The check for URL.revokeObjectURL fixes an issue with Opera 12,
68        // which provides URL.createObjectURL but doesn't properly implement it:
69        urlAPI = (window.createObjectURL && window) ||
70            (window.URL && URL.revokeObjectURL && URL) ||
71            (window.webkitURL && webkitURL);
72
73    loadImage.isInstanceOf = function (type, obj) {
74        // Cross-frame instanceof check
75        return Object.prototype.toString.call(obj) === '[object ' + type + ']';
76    };
77
78    // Transform image orientation based on the given EXIF orientation data:
79    loadImage.transformCoordinates = function (canvas, orientation) {
80        var ctx = canvas.getContext('2d'),
81            width = canvas.width,
82            height = canvas.height;
83        if (orientation > 4) {
84            canvas.width = height;
85            canvas.height = width;
86        }
87        switch (orientation) {
88        case 2:
89            // horizontal flip
90            ctx.translate(width, 0);
91            ctx.scale(-1, 1);
92            break;
93        case 3:
94            // 180 rotate left
95            ctx.translate(width, height);
96            ctx.rotate(Math.PI);
97            break;
98        case 4:
99            // vertical flip
100            ctx.translate(0, height);
101            ctx.scale(1, -1);
102            break;
103        case 5:
104            // vertical flip + 90 rotate right
105            ctx.rotate(0.5 * Math.PI);
106            ctx.scale(1, -1);
107            break;
108        case 6:
109            // 90 rotate right
110            ctx.rotate(0.5 * Math.PI);
111            ctx.translate(0, -height);
112            break;
113        case 7:
114            // horizontal flip + 90 rotate right
115            ctx.rotate(0.5 * Math.PI);
116            ctx.translate(width, -height);
117            ctx.scale(-1, 1);
118            break;
119        case 8:
120            // 90 rotate left
121            ctx.rotate(-0.5 * Math.PI);
122            ctx.translate(-width, 0);
123            break;
124        }
125    };
126
127    // Detects subsampling in JPEG images:
128    loadImage.detectSubsampling = function (img) {
129        var canvas,
130            context;
131        if (img.width * img.height > 1024 * 1024) { // only consider mexapixel images
132            canvas = document.createElement('canvas');
133            canvas.width = canvas.height = 1;
134            context = canvas.getContext('2d');
135            context.drawImage(img, -img.width + 1, 0);
136            // subsampled image becomes half smaller in rendering size.
137            // check alpha channel value to confirm image is covering edge pixel or not.
138            // if alpha value is 0 image is not covering, hence subsampled.
139            return context.getImageData(0, 0, 1, 1).data[3] === 0;
140        }
141        return false;
142    };
143
144    // Detects vertical squash in JPEG images:
145    loadImage.detectVerticalSquash = function (img, correctedHeight) {
146        var canvas = document.createElement('canvas'),
147            context = canvas.getContext('2d'),
148            data,
149            sy,
150            ey,
151            py,
152            alpha;
153        canvas.width = 1;
154        canvas.height = correctedHeight;
155        context.drawImage(img, 0, 0);
156        data = context.getImageData(0, 0, 1, correctedHeight).data;
157        // search image edge pixel position in case it is squashed vertically:
158        sy = 0;
159        ey = correctedHeight;
160        py = correctedHeight;
161        while (py > sy) {
162            alpha = data[(py - 1) * 4 + 3];
163            if (alpha === 0) {
164                ey = py;
165            } else {
166                sy = py;
167            }
168            py = (ey + sy) >> 1;
169        }
170        return (py / correctedHeight) || 1;
171    };
172
173    // Renders image to canvas while working around iOS image scaling bugs:
174    // https://github.com/blueimp/JavaScript-Load-Image/issues/13
175    loadImage.renderImageToCanvas = function (
176        canvas,
177        img,
178        sourceX,
179        sourceY,
180        sourceWidth,
181        sourceHeight,
182        destX,
183        destY,
184        destWidth,
185        destHeight
186    ) {
187        var context = canvas.getContext('2d'),
188            tmpCanvas = document.createElement('canvas'),
189            tileSize = tmpCanvas.width = tmpCanvas.height = 1024,
190            tmpContext = tmpCanvas.getContext('2d'),
191            vertSquashRatio,
192            tileX,
193            tileY;
194        context.save();
195        if (loadImage.detectSubsampling(img)) {
196            sourceWidth /= 2;
197            sourceHeight /= 2;
198        }
199        vertSquashRatio = loadImage.detectVerticalSquash(img, sourceHeight);
200        destWidth = Math.ceil(tileSize * destWidth / sourceWidth);
201        destHeight = Math.ceil(
202            tileSize * destHeight / sourceHeight / vertSquashRatio
203        );
204        destY = 0;
205        tileY = 0;
206        while (tileY < sourceHeight) {
207            destX = 0;
208            tileX = 0;
209            while (tileX < sourceWidth) {
210                tmpContext.clearRect(0, 0, tileSize, tileSize);
211                tmpContext.drawImage(
212                    img,
213                    sourceX,
214                    sourceY,
215                    sourceWidth,
216                    sourceHeight,
217                    -tileX,
218                    -tileY,
219                    sourceWidth,
220                    sourceHeight
221                );
222                context.drawImage(
223                    tmpCanvas,
224                    0,
225                    0,
226                    tileSize,
227                    tileSize,
228                    destX,
229                    destY,
230                    destWidth,
231                    destHeight
232                );
233                tileX += tileSize;
234                destX += destWidth;
235            }
236            tileY += tileSize;
237            destY += destHeight;
238        }
239        context.restore();
240    };
241
242    // Scales the given image (img or canvas HTML element)
243    // using the given options.
244    // Returns a canvas object if the browser supports canvas
245    // and the canvas or crop option is true or a canvas object
246    // is passed as image, else the scaled image:
247    loadImage.scale = function (img, options) {
248        options = options || {};
249        var canvas = document.createElement('canvas'),
250            useCanvas = img.getContext ||
251                ((options.canvas || options.crop || options.orientation) &&
252                    canvas.getContext),
253            width = img.width,
254            height = img.height,
255            sourceWidth = width,
256            sourceHeight = height,
257            sourceX = 0,
258            sourceY = 0,
259            destX = 0,
260            destY = 0,
261            maxWidth,
262            maxHeight,
263            minWidth,
264            minHeight,
265            destWidth,
266            destHeight,
267            scale;
268        if (useCanvas && options.orientation > 4) {
269            maxWidth = options.maxHeight;
270            maxHeight = options.maxWidth;
271            minWidth = options.minHeight;
272            minHeight = options.minWidth;
273        } else {
274            maxWidth = options.maxWidth;
275            maxHeight = options.maxHeight;
276            minWidth = options.minWidth;
277            minHeight = options.minHeight;
278        }
279        if (useCanvas && maxWidth && maxHeight && options.crop) {
280            destWidth = maxWidth;
281            destHeight = maxHeight;
282            if (width / height < maxWidth / maxHeight) {
283                sourceHeight = maxHeight * width / maxWidth;
284                sourceY = (height - sourceHeight) / 2;
285            } else {
286                sourceWidth = maxWidth * height / maxHeight;
287                sourceX = (width - sourceWidth) / 2;
288            }
289        } else {
290            destWidth = width;
291            destHeight = height;
292            scale = Math.max(
293                (minWidth || destWidth) / destWidth,
294                (minHeight || destHeight) / destHeight
295            );
296            if (scale > 1) {
297                destWidth = Math.ceil(destWidth * scale);
298                destHeight = Math.ceil(destHeight * scale);
299            }
300            scale = Math.min(
301                (maxWidth || destWidth) / destWidth,
302                (maxHeight || destHeight) / destHeight
303            );
304            if (scale < 1) {
305                destWidth = Math.ceil(destWidth * scale);
306                destHeight = Math.ceil(destHeight * scale);
307            }
308        }
309        if (useCanvas) {
310            canvas.width = destWidth;
311            canvas.height = destHeight;
312            loadImage.transformCoordinates(
313                canvas,
314                options.orientation
315            );
316            if (img._type === 'image/jpeg') {
317                loadImage.renderImageToCanvas(
318                    canvas,
319                    img,
320                    sourceX,
321                    sourceY,
322                    sourceWidth,
323                    sourceHeight,
324                    destX,
325                    destY,
326                    destWidth,
327                    destHeight
328                );
329            } else {
330                canvas.getContext('2d').drawImage(
331                    img,
332                    sourceX,
333                    sourceY,
334                    sourceWidth,
335                    sourceHeight,
336                    destX,
337                    destY,
338                    destWidth,
339                    destHeight
340                );
341            }
342            return canvas;
343        }
344        img.width = destWidth;
345        img.height = destHeight;
346        return img;
347    };
348
349    loadImage.createObjectURL = function (file) {
350        return urlAPI ? urlAPI.createObjectURL(file) : false;
351    };
352
353    loadImage.revokeObjectURL = function (url) {
354        return urlAPI ? urlAPI.revokeObjectURL(url) : false;
355    };
356
357    // Loads a given File object via FileReader interface,
358    // invokes the callback with the event object (load or error).
359    // The result can be read via event.target.result:
360    loadImage.readFile = function (file, callback, method) {
361        if (window.FileReader && FileReader.prototype.readAsDataURL) {
362            var fileReader = new FileReader();
363            fileReader.onload = fileReader.onerror = callback;
364            method = method || 'readAsDataURL';
365            if (!fileReader[method]) {
366                return false;
367            }
368            fileReader[method](file);
369            return fileReader;
370        }
371        return false;
372    };
373
374    if (typeof define === 'function' && define.amd) {
375        define(function () {
376            return loadImage;
377        });
378    } else {
379        $.loadImage = loadImage;
380    }
381}(this));
Note: See TracBrowser for help on using the repository browser.

Sites map