1// Copyright 2014 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5'use strict'; 6 7/** 8 * The base class for simple filters that only modify the image content 9 * but do not modify the image dimensions. 10 * @constructor 11 * @extends ImageEditor.Mode 12 */ 13ImageEditor.Mode.Adjust = function() { 14 ImageEditor.Mode.apply(this, arguments); 15 this.implicitCommit = true; 16 this.doneMessage_ = null; 17 this.viewportGeneration_ = 0; 18}; 19 20ImageEditor.Mode.Adjust.prototype = {__proto__: ImageEditor.Mode.prototype}; 21 22/** @override */ 23ImageEditor.Mode.Adjust.prototype.getCommand = function() { 24 if (!this.filter_) return null; 25 26 return new Command.Filter(this.name, this.filter_, this.doneMessage_); 27}; 28 29/** @override */ 30ImageEditor.Mode.Adjust.prototype.cleanUpUI = function() { 31 ImageEditor.Mode.prototype.cleanUpUI.apply(this, arguments); 32 this.hidePreview(); 33}; 34 35/** 36 * TODO(JSDOC) 37 */ 38ImageEditor.Mode.Adjust.prototype.hidePreview = function() { 39 if (this.canvas_) { 40 this.canvas_.parentNode.removeChild(this.canvas_); 41 this.canvas_ = null; 42 } 43}; 44 45/** 46 * TODO(JSDOC) 47 */ 48ImageEditor.Mode.Adjust.prototype.cleanUpCaches = function() { 49 this.filter_ = null; 50 this.previewImageData_ = null; 51}; 52 53/** 54 * TODO(JSDOC) 55 */ 56ImageEditor.Mode.Adjust.prototype.reset = function() { 57 ImageEditor.Mode.prototype.reset.call(this); 58 this.hidePreview(); 59 this.cleanUpCaches(); 60}; 61 62/** 63 * TODO(JSDOC) 64 * @param {Object} options // TODO(JSDOC). 65 */ 66ImageEditor.Mode.Adjust.prototype.update = function(options) { 67 ImageEditor.Mode.prototype.update.apply(this, arguments); 68 69 // We assume filter names are used in the UI directly. 70 // This will have to change with i18n. 71 this.filter_ = this.createFilter(options); 72 this.updatePreviewImage(); 73 ImageUtil.trace.resetTimer('preview'); 74 this.filter_(this.previewImageData_, this.originalImageData, 0, 0); 75 ImageUtil.trace.reportTimer('preview'); 76 this.canvas_.getContext('2d').putImageData( 77 this.previewImageData_, 0, 0); 78}; 79 80/** 81 * Copy the source image data for the preview. 82 * Use the cached copy if the viewport has not changed. 83 */ 84ImageEditor.Mode.Adjust.prototype.updatePreviewImage = function() { 85 if (!this.previewImageData_ || 86 this.viewportGeneration_ != this.getViewport().getCacheGeneration()) { 87 this.viewportGeneration_ = this.getViewport().getCacheGeneration(); 88 89 if (!this.canvas_) { 90 this.canvas_ = this.getImageView().createOverlayCanvas(); 91 } 92 93 this.getImageView().setupDeviceBuffer(this.canvas_); 94 95 this.originalImageData = this.getImageView().copyScreenImageData(); 96 this.previewImageData_ = this.getImageView().copyScreenImageData(); 97 } 98}; 99 100/* 101 * Own methods 102 */ 103 104/** 105 * TODO(JSDOC) 106 * @param {Object} options // TODO(JSDOC). 107 * @return {function(ImageData,ImageData,number,number)} Created function. 108 */ 109ImageEditor.Mode.Adjust.prototype.createFilter = function(options) { 110 return filter.create(this.name, options); 111}; 112 113/** 114 * A base class for color filters that are scale independent. 115 * @constructor 116 */ 117ImageEditor.Mode.ColorFilter = function() { 118 ImageEditor.Mode.Adjust.apply(this, arguments); 119}; 120 121ImageEditor.Mode.ColorFilter.prototype = 122 {__proto__: ImageEditor.Mode.Adjust.prototype}; 123 124/** 125 * TODO(JSDOC) 126 * @return {{r: Array.<number>, g: Array.<number>, b: Array.<number>}} 127 * histogram. 128 */ 129ImageEditor.Mode.ColorFilter.prototype.getHistogram = function() { 130 return filter.getHistogram(this.getImageView().getThumbnail()); 131}; 132 133/** 134 * Exposure/contrast filter. 135 * @constructor 136 */ 137ImageEditor.Mode.Exposure = function() { 138 ImageEditor.Mode.ColorFilter.call(this, 'exposure', 'GALLERY_EXPOSURE'); 139}; 140 141ImageEditor.Mode.Exposure.prototype = 142 {__proto__: ImageEditor.Mode.ColorFilter.prototype}; 143 144/** 145 * TODO(JSDOC) 146 * @param {ImageEditor.Toolbar} toolbar The toolbar to populate. 147 */ 148ImageEditor.Mode.Exposure.prototype.createTools = function(toolbar) { 149 toolbar.addRange('brightness', 'GALLERY_BRIGHTNESS', -1, 0, 1, 100); 150 toolbar.addRange('contrast', 'GALLERY_CONTRAST', -1, 0, 1, 100); 151}; 152 153/** 154 * Autofix. 155 * @constructor 156 */ 157ImageEditor.Mode.Autofix = function() { 158 ImageEditor.Mode.ColorFilter.call(this, 'autofix', 'GALLERY_AUTOFIX'); 159 this.doneMessage_ = 'GALLERY_FIXED'; 160}; 161 162ImageEditor.Mode.Autofix.prototype = 163 {__proto__: ImageEditor.Mode.ColorFilter.prototype}; 164 165/** 166 * TODO(JSDOC) 167 * @param {ImageEditor.Toolbar} toolbar The toolbar to populate. 168 */ 169ImageEditor.Mode.Autofix.prototype.createTools = function(toolbar) { 170 var self = this; 171 toolbar.addButton('Apply', this.apply.bind(this)); 172}; 173 174/** 175 * TODO(JSDOC) 176 * @return {boolean} // TODO(JSDOC). 177 */ 178ImageEditor.Mode.Autofix.prototype.isApplicable = function() { 179 return this.getImageView().hasValidImage() && 180 filter.autofix.isApplicable(this.getHistogram()); 181}; 182 183/** 184 * TODO(JSDOC) 185 */ 186ImageEditor.Mode.Autofix.prototype.apply = function() { 187 this.update({histogram: this.getHistogram()}); 188}; 189 190/** 191 * Instant Autofix. 192 * @constructor 193 */ 194ImageEditor.Mode.InstantAutofix = function() { 195 ImageEditor.Mode.Autofix.apply(this, arguments); 196 this.instant = true; 197}; 198 199ImageEditor.Mode.InstantAutofix.prototype = 200 {__proto__: ImageEditor.Mode.Autofix.prototype}; 201 202/** 203 * TODO(JSDOC) 204 */ 205ImageEditor.Mode.InstantAutofix.prototype.setUp = function() { 206 ImageEditor.Mode.Autofix.prototype.setUp.apply(this, arguments); 207 this.apply(); 208}; 209 210/** 211 * Blur filter. 212 * @constructor 213 */ 214ImageEditor.Mode.Blur = function() { 215 ImageEditor.Mode.Adjust.call(this, 'blur'); 216}; 217 218ImageEditor.Mode.Blur.prototype = 219 {__proto__: ImageEditor.Mode.Adjust.prototype}; 220 221/** 222 * TODO(JSDOC) 223 * @param {ImageEditor.Toolbar} toolbar The toolbar to populate. 224 */ 225ImageEditor.Mode.Blur.prototype.createTools = function(toolbar) { 226 toolbar.addRange('strength', 'GALLERY_STRENGTH', 0, 0, 1, 100); 227 toolbar.addRange('radius', 'GALLERY_RADIUS', 1, 1, 3); 228}; 229 230/** 231 * Sharpen filter. 232 * @constructor 233 */ 234ImageEditor.Mode.Sharpen = function() { 235 ImageEditor.Mode.Adjust.call(this, 'sharpen'); 236}; 237 238ImageEditor.Mode.Sharpen.prototype = 239 {__proto__: ImageEditor.Mode.Adjust.prototype}; 240 241/** 242 * TODO(JSDOC) 243 * @param {ImageEditor.Toolbar} toolbar The toolbar to populate. 244 */ 245ImageEditor.Mode.Sharpen.prototype.createTools = function(toolbar) { 246 toolbar.addRange('strength', 'GALLERY_STRENGTH', 0, 0, 1, 100); 247 toolbar.addRange('radius', 'GALLERY_RADIUS', 1, 1, 3); 248}; 249