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

Side by Side Diff: ui/file_manager/image_loader/image_loader.js

Issue 2634213003: Compile image loader in v2 syntax. (Closed)
Patch Set: Fix a unit test. Created 3 years, 11 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
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 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 and resizes an image. 6 * Loads and resizes an image.
7 * @constructor 7 * @constructor
8 */ 8 */
9 function ImageLoader() { 9 function ImageLoader() {
10 /** 10 /**
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
120 }; 120 };
121 121
122 /** 122 /**
123 * Returns the singleton instance. 123 * Returns the singleton instance.
124 * @return {ImageLoader} ImageLoader object. 124 * @return {ImageLoader} ImageLoader object.
125 */ 125 */
126 ImageLoader.getInstance = function() { 126 ImageLoader.getInstance = function() {
127 if (!ImageLoader.instance_) 127 if (!ImageLoader.instance_)
128 ImageLoader.instance_ = new ImageLoader(); 128 ImageLoader.instance_ = new ImageLoader();
129 return ImageLoader.instance_; 129 return ImageLoader.instance_;
130 }; 130 };
131
132 /**
133 * Checks if the options contain any image processing.
134 *
135 * @param {number} width Source width.
136 * @param {number} height Source height.
137 * @param {Object} options Resizing options as a hash array.
138 * @return {boolean} True if yes, false if not.
139 */
140 ImageLoader.shouldProcess = function(width, height, options) {
141 var targetDimensions = ImageLoader.resizeDimensions(width, height, options);
142
143 // Dimensions has to be adjusted.
144 if (targetDimensions.width != width || targetDimensions.height != height)
145 return true;
146
147 // Orientation has to be adjusted.
148 if (!options.orientation.isIdentity())
149 return true;
150
151 // Non-standard color space has to be converted.
152 if (options.colorSpace && options.colorSpace !== ColorSpace.SRGB)
153 return true;
154
155 // No changes required.
156 return false;
157 };
158
159 /**
160 * Calculates dimensions taking into account resize options, such as:
161 * - scale: for scaling,
162 * - maxWidth, maxHeight: for maximum dimensions,
163 * - width, height: for exact requested size.
164 * Returns the target size as hash array with width, height properties.
165 *
166 * @param {number} width Source width.
167 * @param {number} height Source height.
168 * @param {Object} options Resizing options as a hash array.
169 * @return {Object} Dimensions, eg. {width: 100, height: 50}.
170 */
171 ImageLoader.resizeDimensions = function(width, height, options) {
172 var scale = options.scale || 1;
173 var targetDimensions = options.orientation.getSizeAfterCancelling(
174 width * scale, height * scale);
175 var targetWidth = targetDimensions.width;
176 var targetHeight = targetDimensions.height;
177
178 if (options.maxWidth && targetWidth > options.maxWidth) {
179 var scale = options.maxWidth / targetWidth;
180 targetWidth *= scale;
181 targetHeight *= scale;
182 }
183
184 if (options.maxHeight && targetHeight > options.maxHeight) {
185 var scale = options.maxHeight / targetHeight;
186 targetWidth *= scale;
187 targetHeight *= scale;
188 }
189
190 if (options.width)
191 targetWidth = options.width;
192
193 if (options.height)
194 targetHeight = options.height;
195
196 targetWidth = Math.round(targetWidth);
197 targetHeight = Math.round(targetHeight);
198
199 return {width: targetWidth, height: targetHeight};
200 };
201
202 /**
203 * Performs resizing and cropping of the source image into the target canvas.
204 *
205 * @param {HTMLCanvasElement|Image} source Source image or canvas.
206 * @param {HTMLCanvasElement} target Target canvas.
207 * @param {Object} options Resizing options as a hash array.
208 */
209 ImageLoader.resizeAndCrop = function(source, target, options) {
210 // Calculates copy parameters.
211 var copyParameters = ImageLoader.calculateCopyParameters(source, options);
212 target.width = copyParameters.canvas.width;
213 target.height = copyParameters.canvas.height;
214
215 // Apply.
216 var targetContext =
217 /** @type {CanvasRenderingContext2D} */ (target.getContext('2d'));
218 targetContext.save();
219 options.orientation.cancelImageOrientation(
220 targetContext, copyParameters.target.width, copyParameters.target.height);
221 targetContext.drawImage(
222 source,
223 copyParameters.source.x,
224 copyParameters.source.y,
225 copyParameters.source.width,
226 copyParameters.source.height,
227 copyParameters.target.x,
228 copyParameters.target.y,
229 copyParameters.target.width,
230 copyParameters.target.height);
231 targetContext.restore();
232 };
233
234 /**
235 * @typedef {{
236 * source: {x:number, y:number, width:number, height:number},
237 * target: {x:number, y:number, width:number, height:number},
238 * canvas: {width:number, height:number}
239 * }}
240 */
241 ImageLoader.CopyParameters;
242
243 /**
244 * Calculates copy parameters.
245 *
246 * @param {HTMLCanvasElement|Image} source Source image or canvas.
247 * @param {Object} options Resizing options as a hash array.
248 * @return {!ImageLoader.CopyParameters} Calculated copy parameters.
249 */
250 ImageLoader.calculateCopyParameters = function(source, options) {
251 if (options.crop) {
252 // When an image is cropped, target should be a fixed size square.
253 assert(options.width);
254 assert(options.height);
255 assert(options.width === options.height);
256
257 // The length of shorter edge becomes dimension of cropped area in the
258 // source.
259 var cropSourceDimension = Math.min(source.width, source.height);
260
261 return {
262 source: {
263 x: Math.floor((source.width / 2) - (cropSourceDimension / 2)),
264 y: Math.floor((source.height / 2) - (cropSourceDimension / 2)),
265 width: cropSourceDimension,
266 height: cropSourceDimension
267 },
268 target: {
269 x: 0,
270 y: 0,
271 width: options.width,
272 height: options.height
273 },
274 canvas: {
275 width: options.width,
276 height: options.height
277 }
278 };
279 }
280
281 // Target dimension is calculated in the rotated(transformed) coordinate.
282 var targetCanvasDimensions = ImageLoader.resizeDimensions(
283 source.width, source.height, options);
284
285 var targetDimensions = options.orientation.getSizeAfterCancelling(
286 targetCanvasDimensions.width, targetCanvasDimensions.height);
287
288 return {
289 source: {
290 x: 0,
291 y: 0,
292 width: source.width,
293 height: source.height
294 },
295 target: {
296 x: 0,
297 y: 0,
298 width: targetDimensions.width,
299 height: targetDimensions.height
300 },
301 canvas: {
302 width: targetCanvasDimensions.width,
303 height: targetCanvasDimensions.height
304 }
305 };
306 };
307
308 /**
309 * Matrix converts AdobeRGB color space into sRGB color space.
310 * @const {!Array<number>}
311 */
312 ImageLoader.MATRIX_FROM_ADOBE_TO_STANDARD = [
313 1.39836, -0.39836, 0.00000,
314 0.00000, 1.00000, 0.00000,
315 0.00000, -0.04293, 1.04293
316 ];
317
318 /**
319 * Converts the canvas of color space into sRGB.
320 * @param {HTMLCanvasElement} target Target canvas.
321 * @param {ColorSpace} colorSpace Current color space.
322 */
323 ImageLoader.convertColorSpace = function(target, colorSpace) {
324 if (colorSpace === ColorSpace.SRGB)
325 return;
326 if (colorSpace === ColorSpace.ADOBE_RGB) {
327 var matrix = ImageLoader.MATRIX_FROM_ADOBE_TO_STANDARD;
328 var context = target.getContext('2d');
329 var imageData = context.getImageData(0, 0, target.width, target.height);
330 var data = imageData.data;
331 for (var i = 0; i < data.length; i += 4) {
332 // Scale to [0, 1].
333 var adobeR = data[i] / 255;
334 var adobeG = data[i + 1] / 255;
335 var adobeB = data[i + 2] / 255;
336
337 // Revert gannma transformation.
338 adobeR = adobeR <= 0.0556 ? adobeR / 32 : Math.pow(adobeR, 2.2);
339 adobeG = adobeG <= 0.0556 ? adobeG / 32 : Math.pow(adobeG, 2.2);
340 adobeB = adobeB <= 0.0556 ? adobeB / 32 : Math.pow(adobeB, 2.2);
341
342 // Convert color space.
343 var sR = matrix[0] * adobeR + matrix[1] * adobeG + matrix[2] * adobeB;
344 var sG = matrix[3] * adobeR + matrix[4] * adobeG + matrix[5] * adobeB;
345 var sB = matrix[6] * adobeR + matrix[7] * adobeG + matrix[8] * adobeB;
346
347 // Gannma transformation.
348 sR = sR <= 0.0031308 ? 12.92 * sR : 1.055 * Math.pow(sR, 1 / 2.4) - 0.055;
349 sG = sG <= 0.0031308 ? 12.92 * sG : 1.055 * Math.pow(sG, 1 / 2.4) - 0.055;
350 sB = sB <= 0.0031308 ? 12.92 * sB : 1.055 * Math.pow(sB, 1 / 2.4) - 0.055;
351
352 // Scale to [0, 255].
353 data[i] = Math.max(0, Math.min(255, sR * 255));
354 data[i + 1] = Math.max(0, Math.min(255, sG * 255));
355 data[i + 2] = Math.max(0, Math.min(255, sB * 255));
356 }
357 context.putImageData(imageData, 0, 0);
358 }
359 };
OLDNEW
« no previous file with comments | « ui/file_manager/image_loader/compiled_resources2.gyp ('k') | ui/file_manager/image_loader/image_loader_unittest.html » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698