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

Unified Diff: ui/file_manager/gallery/js/gallery_item.js

Issue 1362873003: Gallery: keep exif info if image is saved to a copy. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix failed test case. Created 5 years, 3 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « ui/file_manager/gallery/js/gallery_data_model_unittest.js ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: ui/file_manager/gallery/js/gallery_item.js
diff --git a/ui/file_manager/gallery/js/gallery_item.js b/ui/file_manager/gallery/js/gallery_item.js
index b8b354f8b267d83ea7debcf7f22b0872f7fbc1f1..c0c29a43d1430c03ed1f11bc2beb7cffc0ae16b7 100644
--- a/ui/file_manager/gallery/js/gallery_item.js
+++ b/ui/file_manager/gallery/js/gallery_item.js
@@ -223,7 +223,7 @@ Gallery.Item.prototype.createCopyName_ = function(
Gallery.Item.prototype.isWritableFormat = function() {
var type = FileType.getType(this.entry_);
return type.type === 'image' &&
- (type.subtype === 'JPEG' || type.subtype === 'PNG')
+ (type.subtype === 'JPEG' || type.subtype === 'PNG');
};
/**
@@ -262,7 +262,7 @@ Gallery.Item.prototype.getCopyName = function(dirEntry) {
*
* @param {!VolumeManagerWrapper} volumeManager Volume manager instance.
* @param {!MetadataModel} metadataModel
- * @param {DirectoryEntry} fallbackDir Fallback directory in case the current
+ * @param {!DirectoryEntry} fallbackDir Fallback directory in case the current
* directory is read only.
* @param {!HTMLCanvasElement} canvas Source canvas.
* @param {boolean} overwrite Set true to overwrite original if it's possible.
@@ -271,135 +271,146 @@ Gallery.Item.prototype.getCopyName = function(dirEntry) {
Gallery.Item.prototype.saveToFile = function(
volumeManager, metadataModel, fallbackDir, canvas, overwrite, callback) {
ImageUtil.metrics.startInterval(ImageUtil.getMetricName('SaveTime'));
-
- var name = this.getFileName();
- var newMimeType = this.getNewMimeType_();
-
- var onSuccess = function(entry) {
- var locationInfo = volumeManager.getLocationInfo(entry);
- if (!locationInfo) {
- // Reuse old location info if it fails to obtain location info.
- locationInfo = this.locationInfo_;
- }
- ImageUtil.metrics.recordEnum(ImageUtil.getMetricName('SaveResult'), 1, 2);
- ImageUtil.metrics.recordInterval(ImageUtil.getMetricName('SaveTime'));
-
- this.entry_ = entry;
- this.locationInfo_ = locationInfo;
-
- // Updates the metadata.
- metadataModel.notifyEntriesChanged([this.entry_]);
- Promise.all([
- metadataModel.get([entry], Gallery.PREFETCH_PROPERTY_NAMES),
- new ThumbnailModel(metadataModel).get([entry])
- ]).then(function(metadataLists) {
- this.metadataItem_ = metadataLists[0][0];
- this.thumbnailMetadataItem_ = metadataLists[1][0];
- callback(true);
- }.bind(this), function() {
- callback(false);
- });
- }.bind(this);
-
- var onError = function(error) {
- console.error('Error saving from gallery', name, error);
- ImageUtil.metrics.recordEnum(ImageUtil.getMetricName('SaveResult'), 0, 2);
- if (callback)
- callback(false);
- };
-
- var doSave = function(newFile, fileEntry) {
- var blob;
- var fileWriter;
-
- metadataModel.get(
- [fileEntry],
- ['mediaMimeType', 'contentMimeType', 'ifd', 'exifLittleEndian']
- ).then(function(metadataItems) {
- // Create the blob of new image.
- var metadataItem = metadataItems[0];
- metadataItem.modificationTime = new Date();
- metadataItem.mediaMimeType = newMimeType;
- var metadataEncoder = ImageEncoder.encodeMetadata(
- metadataItem, canvas, /* quality for thumbnail*/ 0.8);
- // Contrary to what one might think 1.0 is not a good default. Opening
- // and saving an typical photo taken with consumer camera increases
- // its file size by 50-100%. Experiments show that 0.9 is much better.
- // It shrinks some photos a bit, keeps others about the same size, but
- // does not visibly lower the quality.
- blob = ImageEncoder.getBlob(canvas, metadataEncoder, 0.9);
- }.bind(this)).then(function() {
- // Create writer.
- return new Promise(function(fullfill, reject) {
- fileEntry.createWriter(fullfill, reject);
- });
- }).then(function(writer) {
- fileWriter = writer;
-
- // Truncates the file to 0 byte if it overwrites.
- return new Promise(function(fulfill, reject) {
- if (!newFile) {
+ var saveResultRecorded = false;
+
+ Promise.all([this.getEntryToWrite_(overwrite, fallbackDir, volumeManager),
+ this.getBlobForSave_(canvas, metadataModel)]).then(function(results) {
+ // Write content to the entry.
+ var fileEntry = results[0];
+ var blob = results[1];
+
+ // Create writer.
+ return new Promise(function(resolve, reject) {
+ fileEntry.createWriter(resolve, reject);
+ }).then(function(fileWriter) {
+ // Truncates the file to 0 byte if it overwrites existing file.
+ return new Promise(function(resolve, reject) {
+ if (util.isSameEntry(fileEntry, this.entry_)) {
fileWriter.onerror = reject;
- fileWriter.onwriteend = fulfill;
+ fileWriter.onwriteend = resolve;
fileWriter.truncate(0);
} else {
- fulfill(null);
+ resolve(null);
}
- });
- }).then(function() {
- // Writes the blob of new image.
- return new Promise(function(fulfill, reject) {
- fileWriter.onerror = reject;
- fileWriter.onwriteend = fulfill;
- fileWriter.write(blob);
- });
- }).then(onSuccess.bind(null, fileEntry))
- .catch(function(error) {
- onError(error);
- if (fileWriter) {
+ }.bind(this)).then(function() {
+ // Writes the blob of new image.
+ return new Promise(function(resolve, reject) {
+ fileWriter.onerror = reject;
+ fileWriter.onwriteend = resolve;
+ fileWriter.write(blob);
+ });
+ }).catch(function(error) {
// Disable all callbacks on the first error.
fileWriter.onerror = null;
fileWriter.onwriteend = null;
+
+ return Promise.reject(error);
+ });
+ }.bind(this)).then(function() {
+ var locationInfo = volumeManager.getLocationInfo(fileEntry);
+ if (!locationInfo) {
+ // Reuse old location info if it fails to obtain location info.
+ locationInfo = this.locationInfo_;
}
- });
- }.bind(this);
-
- var getFile = function(dir, newFile) {
- dir.getFile(name, {create: newFile, exclusive: newFile},
- function(fileEntry) {
- doSave(newFile, fileEntry);
- }.bind(this), onError);
- }.bind(this);
-
- var checkExistence = function(dir) {
- dir.getFile(name, {create: false, exclusive: false},
- getFile.bind(null, dir, false /* existing file */),
- getFile.bind(null, dir, true /* create new file */));
- };
-
- var saveToDir = function(dir) {
- if (overwrite &&
- !this.locationInfo_.isReadOnly &&
- this.isWritableFormat()) {
- checkExistence(dir);
- return;
- }
- this.createCopyName_(dir, newMimeType, function(copyName) {
- this.original_ = false;
- name = copyName;
- checkExistence(dir);
+ ImageUtil.metrics.recordEnum(ImageUtil.getMetricName('SaveResult'), 1, 2);
+ saveResultRecorded = true;
+ ImageUtil.metrics.recordInterval(ImageUtil.getMetricName('SaveTime'));
+
+ this.entry_ = fileEntry;
+ this.locationInfo_ = locationInfo;
+
+ // Updates the metadata.
+ metadataModel.notifyEntriesChanged([this.entry_]);
+ Promise.all([
+ metadataModel.get([this.entry_], Gallery.PREFETCH_PROPERTY_NAMES),
+ new ThumbnailModel(metadataModel).get([this.entry_])
+ ]).then(function(metadataLists) {
+ this.metadataItem_ = metadataLists[0][0];
+ this.thumbnailMetadataItem_ = metadataLists[1][0];
+ callback(true);
+ }.bind(this), function() {
+ callback(false);
+ });
}.bind(this));
- }.bind(this);
-
- // Since in-place editing is not supported on MTP volume, Gallery.app handles
- // MTP volume as read only volume.
- if (this.locationInfo_.isReadOnly ||
- GalleryUtil.isOnMTPVolume(this.entry_, volumeManager)) {
- saveToDir(fallbackDir);
- } else {
- this.entry_.getParent(saveToDir, onError);
- }
+ }.bind(this)).catch(function(error) {
+ console.error('Error saving from gallery', this.entry_.name, error);
+
+ if (!saveResultRecorded)
+ ImageUtil.metrics.recordEnum(ImageUtil.getMetricName('SaveResult'), 0, 2);
+
+ callback(false);
+ }.bind(this));
+};
+
+/**
+ * Returns file entry to write.
+ * @param {boolean} overwrite True to overwrite original file.
+ * @param {!DirectoryEntry} fallbackDirectory Directory to fallback if current
+ * directory is not writable.
+ * @param {!VolumeManagerWrapper} volumeManager
+ * @return {!Promise<!FileEntry>}
+ * @private
+ */
+Gallery.Item.prototype.getEntryToWrite_ = function(
+ overwrite, fallbackDirectory, volumeManager) {
+ return new Promise(function(resolve, reject) {
+ // Since in-place editing is not supported on MTP volume, Gallery.app
+ // handles MTP volume as read only volume.
+ if (this.locationInfo_.isReadOnly ||
+ GalleryUtil.isOnMTPVolume(this.entry_, volumeManager)) {
+ resolve(fallbackDirectory);
+ } else {
+ this.entry_.getParent(resolve, reject);
+ }
+ }.bind(this)).then(function(directory) {
+ return new Promise(function(resolve) {
+ // Find file name.
+ if (overwrite &&
+ !this.locationInfo_.isReadOnly &&
+ this.isWritableFormat()) {
+ resolve(this.getFileName());
+ return;
+ }
+
+ this.createCopyName_(
+ directory, this.getNewMimeType_(), function(copyName) {
+ this.original_ = false;
+ resolve(copyName);
+ }.bind(this));
+ }.bind(this)).then(function(name) {
+ // Get File entry and return.
+ return new Promise(directory.getFile.bind(
+ directory, name, { create: true, exclusive: false }));
+ });
+ }.bind(this));
+};
+
+/**
+ * Returns blob to be saved.
+ * @param {!HTMLCanvasElement} canvas
+ * @param {!MetadataModel} metadataModel
+ * @return {!Promise<!Blob>}
+ * @private
+ */
+Gallery.Item.prototype.getBlobForSave_ = function(canvas, metadataModel) {
+ return metadataModel.get(
+ [this.entry_],
+ ['mediaMimeType', 'contentMimeType', 'ifd', 'exifLittleEndian']
+ ).then(function(metadataItems) {
+ // Create the blob of new image.
+ var metadataItem = metadataItems[0];
+ metadataItem.modificationTime = new Date();
+ metadataItem.mediaMimeType = this.getNewMimeType_();
+ var metadataEncoder = ImageEncoder.encodeMetadata(
+ metadataItem, canvas, /* quality for thumbnail*/ 0.8);
+ // Contrary to what one might think 1.0 is not a good default. Opening
+ // and saving an typical photo taken with consumer camera increases
+ // its file size by 50-100%. Experiments show that 0.9 is much better.
+ // It shrinks some photos a bit, keeps others about the same size, but
+ // does not visibly lower the quality.
+ return ImageEncoder.getBlob(canvas, metadataEncoder, 0.9);
+ }.bind(this));
};
/**
« no previous file with comments | « ui/file_manager/gallery/js/gallery_data_model_unittest.js ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698