OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 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 * Object representing an image item (a photo). | 6 * Object representing an image item (a photo). |
7 * | 7 * |
8 * @param {!FileEntry} entry Image entry. | 8 * @param {!FileEntry} entry Image entry. |
9 * @param {!EntryLocation} locationInfo Entry location information. | 9 * @param {!EntryLocation} locationInfo Entry location information. |
10 * @param {!Object} metadata Metadata for the entry. | 10 * @param {!Object} metadata Metadata for the entry. |
(...skipping 264 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
275 }.bind(this); | 275 }.bind(this); |
276 | 276 |
277 var onError = function(error) { | 277 var onError = function(error) { |
278 console.error('Error saving from gallery', name, error); | 278 console.error('Error saving from gallery', name, error); |
279 ImageUtil.metrics.recordEnum(ImageUtil.getMetricName('SaveResult'), 0, 2); | 279 ImageUtil.metrics.recordEnum(ImageUtil.getMetricName('SaveResult'), 0, 2); |
280 if (opt_callback) | 280 if (opt_callback) |
281 opt_callback(false); | 281 opt_callback(false); |
282 }; | 282 }; |
283 | 283 |
284 var doSave = function(newFile, fileEntry) { | 284 var doSave = function(newFile, fileEntry) { |
285 fileEntry.createWriter(function(fileWriter) { | 285 var metadataPromise = this.fileSystemMetadata_.get( |
286 var writeContent = function() { | 286 [fileEntry], |
287 fileWriter.onwriteend = onSuccess.bind(null, fileEntry); | 287 ['mediaMimeType', 'contentMimeType', 'ifd', 'exifLittleEndian']); |
288 // TODO(hirono): Remove the quality 1 for thumbanils. The code path is | 288 metadataPromise.then(function(metadataItems) { |
289 // no longer used. | 289 fileEntry.createWriter(function(fileWriter) { |
290 var metadataEncoder = ImageEncoder.encodeMetadata( | 290 var writeContent = function() { |
291 this.metadata_, canvas, 1 /* quality */); | 291 fileWriter.onwriteend = onSuccess.bind(null, fileEntry); |
292 // Contrary to what one might think 1.0 is not a good default. Opening | 292 var metadataItem = metadataItems[0]; |
293 // and saving an typical photo taken with consumer camera increases its | 293 metadataItem.modificationTime = new Date(); |
294 // file size by 50-100%. Experiments show that 0.9 is much better. It | 294 var metadataEncoder = ImageEncoder.encodeMetadata( |
295 // shrinks some photos a bit, keeps others about the same size, but does | 295 metadataItem, canvas, /* quality for thumbnail*/ 0.8); |
296 // not visibly lower the quality. | 296 // Contrary to what one might think 1.0 is not a good default. Opening |
297 fileWriter.write(ImageEncoder.getBlob(canvas, metadataEncoder, 0.9)); | 297 // and saving an typical photo taken with consumer camera increases |
298 }.bind(this); | 298 // its file size by 50-100%. Experiments show that 0.9 is much better. |
299 fileWriter.onerror = function(error) { | 299 // It shrinks some photos a bit, keeps others about the same size, but |
300 onError(error); | 300 // does not visibly lower the quality. |
301 // Disable all callbacks on the first error. | 301 fileWriter.write(ImageEncoder.getBlob(canvas, metadataEncoder, 0.9)); |
302 fileWriter.onerror = null; | 302 }.bind(this); |
303 fileWriter.onwriteend = null; | 303 fileWriter.onerror = function(error) { |
304 }; | 304 onError(error); |
305 if (newFile) { | 305 // Disable all callbacks on the first error. |
306 writeContent(); | 306 fileWriter.onerror = null; |
307 } else { | 307 fileWriter.onwriteend = null; |
308 fileWriter.onwriteend = writeContent; | 308 }; |
309 fileWriter.truncate(0); | 309 if (newFile) { |
310 } | 310 writeContent(); |
311 }.bind(this), onError); | 311 } else { |
| 312 fileWriter.onwriteend = writeContent; |
| 313 fileWriter.truncate(0); |
| 314 } |
| 315 }.bind(this), onError); |
| 316 }.bind(this)); |
312 }.bind(this); | 317 }.bind(this); |
313 | 318 |
314 var getFile = function(dir, newFile) { | 319 var getFile = function(dir, newFile) { |
315 dir.getFile(name, {create: newFile, exclusive: newFile}, | 320 dir.getFile(name, {create: newFile, exclusive: newFile}, |
316 function(fileEntry) { | 321 function(fileEntry) { |
317 doSave(newFile, fileEntry); | 322 doSave(newFile, fileEntry); |
318 }.bind(this), onError); | 323 }.bind(this), onError); |
319 }.bind(this); | 324 }.bind(this); |
320 | 325 |
321 var checkExistence = function(dir) { | 326 var checkExistence = function(dir) { |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
372 return Promise.reject(str('GALLERY_FILE_EXISTS')); | 377 return Promise.reject(str('GALLERY_FILE_EXISTS')); |
373 }, function() { | 378 }, function() { |
374 return new Promise( | 379 return new Promise( |
375 this.entry_.moveTo.bind(this.entry_, parentDirectory, newFileName)); | 380 this.entry_.moveTo.bind(this.entry_, parentDirectory, newFileName)); |
376 }.bind(this)); | 381 }.bind(this)); |
377 }.bind(this)); | 382 }.bind(this)); |
378 }.bind(this)).then(function(entry) { | 383 }.bind(this)).then(function(entry) { |
379 this.entry_ = entry; | 384 this.entry_ = entry; |
380 }.bind(this)); | 385 }.bind(this)); |
381 }; | 386 }; |
OLD | NEW |