Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 197 if (options.height) | 197 if (options.height) |
| 198 targetHeight = options.height; | 198 targetHeight = options.height; |
| 199 | 199 |
| 200 targetWidth = Math.round(targetWidth); | 200 targetWidth = Math.round(targetWidth); |
| 201 targetHeight = Math.round(targetHeight); | 201 targetHeight = Math.round(targetHeight); |
| 202 | 202 |
| 203 return {width: targetWidth, height: targetHeight}; | 203 return {width: targetWidth, height: targetHeight}; |
| 204 }; | 204 }; |
| 205 | 205 |
| 206 /** | 206 /** |
| 207 * Performs resizing of the source image into the target canvas. | 207 * Performs resizing and cropping of the source image into the target canvas. |
| 208 * | 208 * |
| 209 * @param {HTMLCanvasElement|Image} source Source image or canvas. | 209 * @param {HTMLCanvasElement|Image} source Source image or canvas. |
| 210 * @param {HTMLCanvasElement} target Target canvas. | 210 * @param {HTMLCanvasElement} target Target canvas. |
| 211 * @param {Object} options Resizing options as a hash array. | 211 * @param {Object} options Resizing options as a hash array. |
| 212 */ | 212 */ |
| 213 ImageLoader.resize = function(source, target, options) { | 213 ImageLoader.resizeAndCrop = function(source, target, options) { |
| 214 var targetDimensions = ImageLoader.resizeDimensions( | 214 // Default orientation is 0deg. |
| 215 var orientation = | |
| 216 ImageOrientation.fromDriveOrientation(options.orientation || 0); | |
| 217 | |
| 218 // Calculates copy parameters. | |
| 219 var copyParameters = ImageLoader.calculateCopyParameters(source, options); | |
| 220 target.width = copyParameters.canvas.width; | |
| 221 target.height = copyParameters.canvas.height; | |
| 222 | |
| 223 // Apply. | |
| 224 var targetContext = | |
| 225 /** @type {CanvasRenderingContext2D} */ (target.getContext('2d')); | |
| 226 targetContext.save(); | |
| 227 orientation.cancelImageOrientation( | |
| 228 targetContext, copyParameters.target.width, copyParameters.target.height); | |
| 229 targetContext.drawImage( | |
| 230 source, | |
| 231 copyParameters.source.x, | |
| 232 copyParameters.source.y, | |
| 233 copyParameters.source.width, | |
| 234 copyParameters.source.height, | |
| 235 copyParameters.target.x, | |
| 236 copyParameters.target.y, | |
| 237 copyParameters.target.width, | |
| 238 copyParameters.target.height); | |
| 239 targetContext.restore(); | |
| 240 }; | |
| 241 | |
| 242 /** | |
| 243 * @typedef {{ | |
| 244 * source: {x:number, y:number, width:number, height:number}, | |
| 245 * target: {x:number, y:number, width:number, height:number}, | |
| 246 * canvas: {width:number, height:number} | |
| 247 * }} | |
| 248 */ | |
| 249 ImageLoader.CopyParameters; | |
| 250 | |
| 251 /** | |
| 252 * Calculates copy parameters. | |
| 253 * | |
| 254 * @param {HTMLCanvasElement|Image} source Source image or canvas. | |
| 255 * @param {Object} options Resizing options as a hash array. | |
| 256 * @return {!ImageLoader.CopyParameters} Calculated copy parameters. | |
| 257 */ | |
| 258 ImageLoader.calculateCopyParameters = function(source, options) { | |
| 259 if (options.crop) { | |
| 260 // When an image is cropped, target should be a fixed size square. | |
| 261 assert(options.width); | |
| 262 assert(options.height); | |
| 263 assert(options.width === options.height); | |
| 264 | |
| 265 // The length of shorter edge becomes dimension of cropped area in the | |
| 266 // source. | |
| 267 var cropSourceDimension = | |
| 268 source.width < source.height ? source.width : source.height; | |
|
hirono
2015/05/13 09:02:24
nit: You can use Math.min.
yawano
2015/05/13 09:11:10
Done.
| |
| 269 | |
| 270 return { | |
| 271 source: { | |
| 272 x: Math.floor((source.width / 2) - (cropSourceDimension / 2)), | |
| 273 y: Math.floor((source.height / 2) - (cropSourceDimension / 2)), | |
| 274 width: cropSourceDimension, | |
| 275 height: cropSourceDimension | |
| 276 }, | |
| 277 target: { | |
| 278 x: 0, | |
| 279 y: 0, | |
| 280 width: options.width, | |
| 281 height: options.height | |
| 282 }, | |
| 283 canvas: { | |
| 284 width: options.width, | |
| 285 height: options.height | |
| 286 } | |
| 287 }; | |
| 288 } | |
| 289 | |
| 290 // Target dimension is calculated in the rotated(transformed) coordinate. | |
| 291 var targetCanvasDimensions = ImageLoader.resizeDimensions( | |
| 215 source.width, source.height, options); | 292 source.width, source.height, options); |
| 216 | 293 |
| 217 // Default orientation is 0deg. | 294 var targetDimensions = targetCanvasDimensions; |
| 218 var orientation = options.orientation || new ImageOrientation(1, 0, 0, 1); | 295 if (options.orientation && options.orientation % 2) { |
| 219 var size = orientation.getSizeAfterCancelling( | 296 console.log(JSON.stringify(targetCanvasDimensions)); |
|
hirono
2015/05/13 09:02:24
Remove the debug log.
yawano
2015/05/13 09:11:10
Done. Thank you!
| |
| 220 targetDimensions.width, targetDimensions.height); | 297 targetDimensions = { |
| 221 target.width = size.width; | 298 width: targetCanvasDimensions.height, |
| 222 target.height = size.height; | 299 height: targetCanvasDimensions.width |
| 300 }; | |
| 301 } | |
| 223 | 302 |
| 224 var targetContext = target.getContext('2d'); | 303 return { |
| 225 targetContext.save(); | 304 source: { |
| 226 orientation.cancelImageOrientation( | 305 x: 0, |
| 227 targetContext, targetDimensions.width, targetDimensions.height); | 306 y: 0, |
| 228 targetContext.drawImage( | 307 width: source.width, |
| 229 source, | 308 height: source.height |
| 230 0, 0, source.width, source.height, | 309 }, |
| 231 0, 0, targetDimensions.width, targetDimensions.height); | 310 target: { |
| 232 targetContext.restore(); | 311 x: 0, |
| 312 y: 0, | |
| 313 width: targetDimensions.width, | |
| 314 height: targetDimensions.height | |
| 315 }, | |
| 316 canvas: { | |
| 317 width: targetCanvasDimensions.width, | |
| 318 height: targetCanvasDimensions.height | |
| 319 } | |
| 320 }; | |
| 233 }; | 321 }; |
| 234 | 322 |
| 235 /** | 323 /** |
| 236 * Matrix converts AdobeRGB color space into sRGB color space. | 324 * Matrix converts AdobeRGB color space into sRGB color space. |
| 237 * @const {!Array<number>} | 325 * @const {!Array<number>} |
| 238 */ | 326 */ |
| 239 ImageLoader.MATRIX_FROM_ADOBE_TO_STANDARD = [ | 327 ImageLoader.MATRIX_FROM_ADOBE_TO_STANDARD = [ |
| 240 1.39836, -0.39836, 0.00000, | 328 1.39836, -0.39836, 0.00000, |
| 241 0.00000, 1.00000, 0.00000, | 329 0.00000, 1.00000, 0.00000, |
| 242 0.00000, -0.04293, 1.04293 | 330 0.00000, -0.04293, 1.04293 |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 277 sB = sB <= 0.0031308 ? 12.92 * sB : 1.055 * Math.pow(sB, 1 / 2.4) - 0.055; | 365 sB = sB <= 0.0031308 ? 12.92 * sB : 1.055 * Math.pow(sB, 1 / 2.4) - 0.055; |
| 278 | 366 |
| 279 // Scale to [0, 255]. | 367 // Scale to [0, 255]. |
| 280 data[i] = Math.max(0, Math.min(255, sR * 255)); | 368 data[i] = Math.max(0, Math.min(255, sR * 255)); |
| 281 data[i + 1] = Math.max(0, Math.min(255, sG * 255)); | 369 data[i + 1] = Math.max(0, Math.min(255, sG * 255)); |
| 282 data[i + 2] = Math.max(0, Math.min(255, sB * 255)); | 370 data[i + 2] = Math.max(0, Math.min(255, sB * 255)); |
| 283 } | 371 } |
| 284 context.putImageData(imageData, 0, 0); | 372 context.putImageData(imageData, 0, 0); |
| 285 } | 373 } |
| 286 }; | 374 }; |
| OLD | NEW |