Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1531)

Side by Side Diff: chrome/browser/resources/file_manager/js/media/media_util.js

Issue 12304013: Introduce Image loader extension. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Cleanup. Created 7 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 /** 5 /**
6 * Loads a thumbnail using provided url. In CANVAS mode, loaded images 6 * Loads a thumbnail using provided url. In CANVAS mode, loaded images
7 * are attached as <canvas> element, while in IMAGE mode as <img>. 7 * are attached as <canvas> element, while in IMAGE mode as <img>.
8 * <canvas> renders faster than <img>, however has bigger memory overhead. 8 * <canvas> renders faster than <img>, however has bigger memory overhead.
9 * 9 *
10 * @param {string} url File URL. 10 * @param {string} url File URL.
(...skipping 20 matching lines...) Expand all
31 if (apps[i].docIcon && apps[i].isPrimary) { 31 if (apps[i].docIcon && apps[i].isPrimary) {
32 this.fallbackUrl_ = apps[i].docIcon; 32 this.fallbackUrl_ = apps[i].docIcon;
33 break; 33 break;
34 } 34 }
35 } 35 }
36 } 36 }
37 37
38 if (opt_metadata.thumbnail && opt_metadata.thumbnail.url) { 38 if (opt_metadata.thumbnail && opt_metadata.thumbnail.url) {
39 this.thumbnailUrl_ = opt_metadata.thumbnail.url; 39 this.thumbnailUrl_ = opt_metadata.thumbnail.url;
40 this.transform_ = opt_metadata.thumbnail.transform; 40 this.transform_ = opt_metadata.thumbnail.transform;
41 } else if (FileType.isImage(url) && 41 } else if (FileType.isImage(url)) {
42 ThumbnailLoader.canUseImageUrl_(opt_metadata)) {
43 this.thumbnailUrl_ = url; 42 this.thumbnailUrl_ = url;
44 this.transform_ = opt_metadata.media && opt_metadata.media.imageTransform; 43 this.transform_ = opt_metadata.media && opt_metadata.media.imageTransform;
45 } else if (this.fallbackUrl_) { 44 } else if (this.fallbackUrl_) {
46 // Use fallback as the primary thumbnail. 45 // Use fallback as the primary thumbnail.
47 this.thumbnailUrl_ = this.fallbackUrl_; 46 this.thumbnailUrl_ = this.fallbackUrl_;
48 this.fallbackUrl_ = null; 47 this.fallbackUrl_ = null;
49 } // else the generic thumbnail based on the media type will be used. 48 } // else the generic thumbnail based on the media type will be used.
50 } 49 }
51 50
52 /** 51 /**
53 * Files with more pixels won't have thumbnails.
54 */
55 ThumbnailLoader.MAX_PIXEL_COUNT = 1 << 21; // 2 MPix
56
57 /**
58 * Files of bigger size won't have thumbnails.
59 */
60 ThumbnailLoader.MAX_FILE_SIZE = 1 << 20; // 1 Mb
61
62 /**
63 * In percents (0.0 - 1.0), how much area can be cropped to fill an image 52 * In percents (0.0 - 1.0), how much area can be cropped to fill an image
64 * in a container, when loading a thumbnail in FillMode.AUTO mode. 53 * in a container, when loading a thumbnail in FillMode.AUTO mode.
65 * The specified 30% value allows to fill 16:9, 3:2 pictures in 4:3 element. 54 * The specified 30% value allows to fill 16:9, 3:2 pictures in 4:3 element.
66 * @type {number} 55 * @type {number}
67 */ 56 */
68 ThumbnailLoader.AUTO_FILL_THRESHOLD = 0.3; 57 ThumbnailLoader.AUTO_FILL_THRESHOLD = 0.3;
69 58
70 /** 59 /**
71 * Type of displaying a thumbnail within a box. 60 * Type of displaying a thumbnail within a box.
72 * @enum 61 * @enum
73 */ 62 */
74 ThumbnailLoader.FillMode = { 63 ThumbnailLoader.FillMode = {
75 FILL: 0, // Fill whole box. Image may be cropped. 64 FILL: 0, // Fill whole box. Image may be cropped.
76 FIT: 1, // Keep aspect ratio, do not crop. 65 FIT: 1, // Keep aspect ratio, do not crop.
77 AUTO: 2 // Try to fill, but if incompatible aspect ratio, then fit. 66 AUTO: 2 // Try to fill, but if incompatible aspect ratio, then fit.
78 }; 67 };
79 68
80 /** 69 /**
81 * Type of element to store the image. 70 * Type of element to store the image.
82 * @enum 71 * @enum
83 */ 72 */
84 ThumbnailLoader.LoaderType = { 73 ThumbnailLoader.LoaderType = {
85 IMAGE: 0, 74 IMAGE: 0,
86 CANVAS: 1 75 CANVAS: 1
87 }; 76 };
88 77
89 /** 78 /**
90 * If an image file does not have an embedded thumbnail we might want to use 79 * Maximum thumbnail's width when generating from the full resolution image.
91 * the image itself as a thumbnail. If the image is too large it hurts 80 * @const
92 * the performance a lot so we allow it only for moderately sized files. 81 * @type {number}
93 *
94 * @param {Object} metadata Metadata object.
95 * @return {boolean} Whether it is OK to use the image url for a preview.
96 * @private
97 */ 82 */
98 ThumbnailLoader.canUseImageUrl_ = function(metadata) { 83 ThumbnailLoader.THUMBNAIL_MAX_WIDTH = 500;
99 return (metadata.filesystem && metadata.filesystem.size && 84
100 metadata.filesystem.size <= ThumbnailLoader.MAX_FILE_SIZE) || 85 /**
101 (metadata.media && metadata.media.width && metadata.media.height && 86 * Maximum thumbnail's height when generating from the full resolution image.
102 metadata.media.width * metadata.media.height <= 87 * @const
103 ThumbnailLoader.MAX_PIXEL_COUNT); 88 * @type {number}
104 }; 89 */
90 ThumbnailLoader.THUMBNAIL_MAX_HEIGHT = 500;
105 91
106 /** 92 /**
107 * 93 *
108 * @param {HTMLElement} box Container element. 94 * @param {HTMLElement} box Container element.
109 * @param {ThumbnailLoader.FillMode} fillMode Fill mode. 95 * @param {ThumbnailLoader.FillMode} fillMode Fill mode.
110 * @param {function(Image, object} opt_onSuccess Success callback, 96 * @param {function(Image, object} opt_onSuccess Success callback,
111 * accepts the image and the transform. 97 * accepts the image and the transform.
112 * @param {function} opt_onError Error callback. 98 * @param {function} opt_onError Error callback.
113 * @param {function} opt_onGeneric Callback for generic image used. 99 * @param {function} opt_onGeneric Callback for generic image used.
114 */ 100 */
(...skipping 20 matching lines...) Expand all
135 new ThumbnailLoader(this.fallbackUrl_, 121 new ThumbnailLoader(this.fallbackUrl_,
136 this.loaderType_, 122 this.loaderType_,
137 null, 123 null,
138 this.mediaType_). 124 this.mediaType_).
139 load(box, fillMode, opt_onSuccess); 125 load(box, fillMode, opt_onSuccess);
140 } else { 126 } else {
141 box.setAttribute('generic-thumbnail', this.mediaType_); 127 box.setAttribute('generic-thumbnail', this.mediaType_);
142 } 128 }
143 }.bind(this); 129 }.bind(this);
144 130
145 if (this.image_.src == this.thumbnailUrl_) { 131 if (this.image_.src) {
146 console.warn('Thumnbnail already loaded: ' + this.thumbnailUrl_); 132 console.warn('Thumbnail already loaded: ' + this.thumbnailUrl_);
147 return; 133 return;
148 } 134 }
149 135
150 util.loadImage(this.image_, this.thumbnailUrl_); 136 // TODO(mtomasz): Smarter calculation of the requested size.
137 var wasAttached = box.ownerDocument.contains(box);
138 var taskId = util.loadImage(
139 this.image_,
140 this.thumbnailUrl_,
141 { maxWidth: ThumbnailLoader.THUMBNAIL_MAX_WIDTH,
142 maxHeight: ThumbnailLoader.THUMBNAIL_MAX_HEIGHT,
143 cache: true },
144 function() {
145 // If was attached, and it is not anymore, then cancel downloading.
146 var isAttached = box.ownerDocument.contains(box);
147 if (wasAttached && !isAttached)
148 return false;
149 return true;
150 });
151
152 if (!taskId)
153 this.image_.classList.add('cached');
151 }; 154 };
152 155
153 /** 156 /**
154 * @return {boolean} True if a valid image is loaded. 157 * @return {boolean} True if a valid image is loaded.
155 */ 158 */
156 ThumbnailLoader.prototype.hasValidImage = function() { 159 ThumbnailLoader.prototype.hasValidImage = function() {
157 return !!(this.image_ && this.image_.width && this.image_.height); 160 return !!(this.image_ && this.image_.width && this.image_.height);
158 }; 161 };
159 162
160 /** 163 /**
(...skipping 27 matching lines...) Expand all
188 ThumbnailLoader.prototype.loadDetachedImage = function(callback) { 191 ThumbnailLoader.prototype.loadDetachedImage = function(callback) {
189 if (!this.thumbnailUrl_) { 192 if (!this.thumbnailUrl_) {
190 callback(true); 193 callback(true);
191 return; 194 return;
192 } 195 }
193 196
194 this.canvasUpToDate_ = false; 197 this.canvasUpToDate_ = false;
195 this.image_ = new Image(); 198 this.image_ = new Image();
196 this.image_.onload = callback.bind(null, true); 199 this.image_.onload = callback.bind(null, true);
197 this.image_.onerror = callback.bind(null, false); 200 this.image_.onerror = callback.bind(null, false);
198 util.loadImage(this.image_, this.thumbnailUrl_); 201
202 // TODO(mtomasz): Smarter calculation of the requested size.
203 var taskId = util.loadImage(
204 this.image_,
205 this.thumbnailUrl_,
206 { maxWidth: ThumbnailLoader.THUMBNAIL_MAX_WIDTH,
207 maxHeight: ThumbnailLoader.THUMBNAIL_MAX_HEIGHT,
208 cache: true });
209
210 if (!taskId)
211 this.image_.classList.add('cached');
199 }; 212 };
200 213
201 /** 214 /**
202 * Attach the image to a given element. 215 * Attach the image to a given element.
203 * @param {Element} container Parent element. 216 * @param {Element} container Parent element.
204 * @param {ThumbnailLoader.FillMode} fillMode Fill mode. 217 * @param {ThumbnailLoader.FillMode} fillMode Fill mode.
205 */ 218 */
206 ThumbnailLoader.prototype.attachImage = function(container, fillMode) { 219 ThumbnailLoader.prototype.attachImage = function(container, fillMode) {
207 if (!this.hasValidImage()) { 220 if (!this.hasValidImage()) {
208 container.setAttribute('generic-thumbnail', this.mediaType_); 221 container.setAttribute('generic-thumbnail', this.mediaType_);
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
310 323
311 function percent(fraction) { 324 function percent(fraction) {
312 return (fraction * 100).toFixed(2) + '%'; 325 return (fraction * 100).toFixed(2) + '%';
313 } 326 }
314 327
315 img.style.width = percent(fractionX); 328 img.style.width = percent(fractionX);
316 img.style.height = percent(fractionY); 329 img.style.height = percent(fractionY);
317 img.style.left = percent((1 - fractionX) / 2); 330 img.style.left = percent((1 - fractionX) / 2);
318 img.style.top = percent((1 - fractionY) / 2); 331 img.style.top = percent((1 - fractionY) / 2);
319 }; 332 };
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698