Commit 4d57cb47 authored by hirono's avatar hirono Committed by Commit bot

Start to use new metadata item in ImageEncoder.

BUG=410766
TEST=None

Review URL: https://codereview.chromium.org/936143003

Cr-Commit-Position: refs/heads/master@{#318188}
parent 42e39712
...@@ -282,33 +282,38 @@ Gallery.Item.prototype.saveToFile = function( ...@@ -282,33 +282,38 @@ Gallery.Item.prototype.saveToFile = function(
}; };
var doSave = function(newFile, fileEntry) { var doSave = function(newFile, fileEntry) {
fileEntry.createWriter(function(fileWriter) { var metadataPromise = this.fileSystemMetadata_.get(
var writeContent = function() { [fileEntry],
fileWriter.onwriteend = onSuccess.bind(null, fileEntry); ['mediaMimeType', 'contentMimeType', 'ifd', 'exifLittleEndian']);
// TODO(hirono): Remove the quality 1 for thumbanils. The code path is metadataPromise.then(function(metadataItems) {
// no longer used. fileEntry.createWriter(function(fileWriter) {
var metadataEncoder = ImageEncoder.encodeMetadata( var writeContent = function() {
this.metadata_, canvas, 1 /* quality */); fileWriter.onwriteend = onSuccess.bind(null, fileEntry);
// Contrary to what one might think 1.0 is not a good default. Opening var metadataItem = metadataItems[0];
// and saving an typical photo taken with consumer camera increases its metadataItem.modificationTime = new Date();
// file size by 50-100%. Experiments show that 0.9 is much better. It var metadataEncoder = ImageEncoder.encodeMetadata(
// shrinks some photos a bit, keeps others about the same size, but does metadataItem, canvas, /* quality for thumbnail*/ 0.8);
// not visibly lower the quality. // Contrary to what one might think 1.0 is not a good default. Opening
fileWriter.write(ImageEncoder.getBlob(canvas, metadataEncoder, 0.9)); // and saving an typical photo taken with consumer camera increases
}.bind(this); // its file size by 50-100%. Experiments show that 0.9 is much better.
fileWriter.onerror = function(error) { // It shrinks some photos a bit, keeps others about the same size, but
onError(error); // does not visibly lower the quality.
// Disable all callbacks on the first error. fileWriter.write(ImageEncoder.getBlob(canvas, metadataEncoder, 0.9));
fileWriter.onerror = null; }.bind(this);
fileWriter.onwriteend = null; fileWriter.onerror = function(error) {
}; onError(error);
if (newFile) { // Disable all callbacks on the first error.
writeContent(); fileWriter.onerror = null;
} else { fileWriter.onwriteend = null;
fileWriter.onwriteend = writeContent; };
fileWriter.truncate(0); if (newFile) {
} writeContent();
}.bind(this), onError); } else {
fileWriter.onwriteend = writeContent;
fileWriter.truncate(0);
}
}.bind(this), onError);
}.bind(this));
}.bind(this); }.bind(this);
var getFile = function(dir, newFile) { var getFile = function(dir, newFile) {
......
...@@ -63,6 +63,13 @@ function testSaveToFile(callback) { ...@@ -63,6 +63,13 @@ function testSaveToFile(callback) {
{isReadOnly: false}, {isReadOnly: false},
{name: 'oldMetadata'}, {name: 'oldMetadata'},
metadataCache, metadataCache,
// Mock of FileSystemMetadata.
{
get: function() {
return Promise.resolve([{}]);
},
notifyEntriesChanged: function() {}
},
/* original */ true); /* original */ true);
assertEquals('oldMetadata', item.getMetadata().name); assertEquals('oldMetadata', item.getMetadata().name);
assertFalse(fetchedMediaCleared); assertFalse(fetchedMediaCleared);
......
...@@ -5,18 +5,35 @@ ...@@ -5,18 +5,35 @@
/** /**
* The Exif metadata encoder. * The Exif metadata encoder.
* Uses the metadata format as defined by ExifParser. * Uses the metadata format as defined by ExifParser.
* @param {!Object} originalMetadata Metadata to encode. * @param {!MetadataItem} originalMetadata Metadata to encode.
* @constructor * @constructor
* @extends {ImageEncoder.MetadataEncoder} * @extends {ImageEncoder.MetadataEncoder}
* @struct * @struct
*/ */
function ExifEncoder(originalMetadata) { function ExifEncoder(originalMetadata) {
ImageEncoder.MetadataEncoder.apply(this, arguments); ImageEncoder.MetadataEncoder.apply(this, arguments);
/**
if (this.metadata_.media && this.metadata_.media.ifd) * Image File Directory obtained from EXIF header.
this.ifd_ = this.metadata_.media.ifd; * @private {!Object}
else * @const
this.ifd_ = {}; */
this.ifd_ = /** @type {!Object} */(
JSON.parse(JSON.stringify(originalMetadata.ifd || {})));
/**
* Note use little endian if the original metadata does not have the
* information.
* @private {boolean}
* @const
*/
this.exifLittleEndian_ = !!originalMetadata.exifLittleEndian;
/**
* Modification time to be stored in EXIF header.
* @private {!Date}
* @const
*/
this.modificationTime_ = assert(originalMetadata.modificationTime);
} }
ExifEncoder.prototype = {__proto__: ImageEncoder.MetadataEncoder.prototype}; ExifEncoder.prototype = {__proto__: ImageEncoder.MetadataEncoder.prototype};
...@@ -32,11 +49,11 @@ ExifEncoder.SOFTWARE = 'Chrome OS Gallery App\0'; ...@@ -32,11 +49,11 @@ ExifEncoder.SOFTWARE = 'Chrome OS Gallery App\0';
/** /**
* @param {!HTMLCanvasElement} canvas * @param {!HTMLCanvasElement} canvas
* @param {Date=} opt_modificationDateTime
* @override * @override
*/ */
ExifEncoder.prototype.setImageData = ExifEncoder.prototype.setImageData = function(canvas) {
function(canvas, opt_modificationDateTime) { ImageEncoder.MetadataEncoder.prototype.setImageData.call(this, canvas);
var image = this.ifd_.image; var image = this.ifd_.image;
if (!image) if (!image)
image = this.ifd_.image = {}; image = this.ifd_.image = {};
...@@ -54,11 +71,7 @@ ExifEncoder.prototype.setImageData = ...@@ -54,11 +71,7 @@ ExifEncoder.prototype.setImageData =
ExifEncoder.findOrCreateTag(exif, Exif.Tag.X_DIMENSION).value = canvas.width; ExifEncoder.findOrCreateTag(exif, Exif.Tag.X_DIMENSION).value = canvas.width;
ExifEncoder.findOrCreateTag(exif, Exif.Tag.Y_DIMENSION).value = canvas.height; ExifEncoder.findOrCreateTag(exif, Exif.Tag.Y_DIMENSION).value = canvas.height;
this.metadata_.width = canvas.width;
this.metadata_.height = canvas.height;
// Always save in default orientation. // Always save in default orientation.
delete this.metadata_['imageTransform'];
ExifEncoder.findOrCreateTag(image, Exif.Tag.ORIENTATION).value = 1; ExifEncoder.findOrCreateTag(image, Exif.Tag.ORIENTATION).value = 1;
// Update software name. // Update software name.
...@@ -75,15 +88,14 @@ ExifEncoder.prototype.setImageData = ...@@ -75,15 +88,14 @@ ExifEncoder.prototype.setImageData =
return str; return str;
}; };
var modificationDateTime = opt_modificationDateTime || new Date();
var dateTimeTag = ExifEncoder.findOrCreateTag(image, Exif.Tag.DATETIME, 2); var dateTimeTag = ExifEncoder.findOrCreateTag(image, Exif.Tag.DATETIME, 2);
dateTimeTag.value = dateTimeTag.value =
padNumWithZero(modificationDateTime.getFullYear(), 4) + ':' + padNumWithZero(this.modificationTime_.getFullYear(), 4) + ':' +
padNumWithZero(modificationDateTime.getMonth() + 1, 2) + ':' + padNumWithZero(this.modificationTime_.getMonth() + 1, 2) + ':' +
padNumWithZero(modificationDateTime.getDate(), 2) + ' ' + padNumWithZero(this.modificationTime_.getDate(), 2) + ' ' +
padNumWithZero(modificationDateTime.getHours(), 2) + ':' + padNumWithZero(this.modificationTime_.getHours(), 2) + ':' +
padNumWithZero(modificationDateTime.getMinutes(), 2) + ':' + padNumWithZero(this.modificationTime_.getMinutes(), 2) + ':' +
padNumWithZero(modificationDateTime.getSeconds(), 2) + '\0'; padNumWithZero(this.modificationTime_.getSeconds(), 2) + '\0';
dateTimeTag.componentCount = 20; dateTimeTag.componentCount = 20;
}; };
...@@ -91,24 +103,28 @@ ExifEncoder.prototype.setImageData = ...@@ -91,24 +103,28 @@ ExifEncoder.prototype.setImageData =
* @override * @override
*/ */
ExifEncoder.prototype.setThumbnailData = function(canvas, quality) { ExifEncoder.prototype.setThumbnailData = function(canvas, quality) {
// Empirical formula with reasonable behavior: if (canvas) {
// 10K for 1Mpix, 30K for 5Mpix, 50K for 9Mpix and up. // Empirical formula with reasonable behavior:
var pixelCount = this.metadata_.width * this.metadata_.height; // 10K for 1Mpix, 30K for 5Mpix, 50K for 9Mpix and up.
var maxEncodedSize = 5000 * Math.min(10, 1 + pixelCount / 1000000); var pixelCount = this.imageWidth * this.imageHeight;
var maxEncodedSize = 5000 * Math.min(10, 1 + pixelCount / 1000000);
var DATA_URL_PREFIX = 'data:' + this.metadata_.media.mimeType + ';base64,'; var DATA_URL_PREFIX = 'data:image/jpeg;base64,';
var BASE64_BLOAT = 4 / 3; var BASE64_BLOAT = 4 / 3;
var maxDataURLLength = var maxDataURLLength =
DATA_URL_PREFIX.length + Math.ceil(maxEncodedSize * BASE64_BLOAT); DATA_URL_PREFIX.length + Math.ceil(maxEncodedSize * BASE64_BLOAT);
for (; quality > 0.2; quality *= 0.8) {
for (;; quality *= 0.8) { ImageEncoder.MetadataEncoder.prototype.setThumbnailData.call(
ImageEncoder.MetadataEncoder.prototype.setThumbnailData.call( this, canvas, quality);
this, canvas, quality); // If the obtained thumbnail URL is too long, reset the URL and try again
if (this.metadata_.thumbnailURL.length <= maxDataURLLength || quality < 0.2) // with less quality value.
if (this.thumbnailDataUrl.length > maxDataURLLength) {
this.thumbnailDataUrl = '';
continue;
}
break; break;
}
} }
if (this.thumbnailDataUrl) {
if (canvas && this.metadata_.thumbnailURL.length <= maxDataURLLength) {
var thumbnail = this.ifd_.thumbnail; var thumbnail = this.ifd_.thumbnail;
if (!thumbnail) if (!thumbnail)
thumbnail = this.ifd_.thumbnail = {}; thumbnail = this.ifd_.thumbnail = {};
...@@ -130,13 +146,8 @@ ExifEncoder.prototype.setThumbnailData = function(canvas, quality) { ...@@ -130,13 +146,8 @@ ExifEncoder.prototype.setThumbnailData = function(canvas, quality) {
ExifEncoder.findOrCreateTag(this.ifd_.image, Exif.Tag.COMPRESSION).value = ExifEncoder.findOrCreateTag(this.ifd_.image, Exif.Tag.COMPRESSION).value =
6; 6;
} else { } else {
console.warn( if (this.ifd_.thumbnail)
'Thumbnail URL too long: ' + this.metadata_.thumbnailURL.length);
// Delete thumbnail ifd so that it is not written out to a file, but
// keep thumbnailURL for display purposes.
if (this.ifd_.thumbnail) {
delete this.ifd_.thumbnail; delete this.ifd_.thumbnail;
}
} }
}; };
...@@ -207,7 +218,7 @@ ExifEncoder.prototype.encode = function() { ...@@ -207,7 +218,7 @@ ExifEncoder.prototype.encode = function() {
// can be directly mapped to offsets as encoded in the dictionaries. // can be directly mapped to offsets as encoded in the dictionaries.
var bw = new ByteWriter(bytes.buffer, HEADER_SIZE); var bw = new ByteWriter(bytes.buffer, HEADER_SIZE);
if (this.metadata_.littleEndian) { if (this.exifLittleEndian_) {
bw.setByteOrder(ByteWriter.ByteOrder.LITTLE_ENDIAN); bw.setByteOrder(ByteWriter.ByteOrder.LITTLE_ENDIAN);
bw.writeScalar(Exif.Align.LITTLE, 2); bw.writeScalar(Exif.Align.LITTLE, 2);
} else { } else {
...@@ -246,8 +257,7 @@ ExifEncoder.prototype.encode = function() { ...@@ -246,8 +257,7 @@ ExifEncoder.prototype.encode = function() {
this.ifd_.thumbnail, this.ifd_.thumbnail,
[Exif.Tag.JPG_THUMB_OFFSET, Exif.Tag.JPG_THUMB_LENGTH]); [Exif.Tag.JPG_THUMB_OFFSET, Exif.Tag.JPG_THUMB_LENGTH]);
var thumbnailDecoded = var thumbnailDecoded = ImageEncoder.decodeDataURL(this.thumbnailDataUrl);
ImageEncoder.decodeDataURL(this.metadata_.thumbnailURL);
bw.resolveOffset(Exif.Tag.JPG_THUMB_OFFSET); bw.resolveOffset(Exif.Tag.JPG_THUMB_OFFSET);
bw.resolve(Exif.Tag.JPG_THUMB_LENGTH, thumbnailDecoded.length); bw.resolve(Exif.Tag.JPG_THUMB_LENGTH, thumbnailDecoded.length);
bw.writeString(thumbnailDecoded); bw.writeString(thumbnailDecoded);
......
...@@ -11,56 +11,54 @@ function testExifEncodeAndDecode() { ...@@ -11,56 +11,54 @@ function testExifEncodeAndDecode() {
var data = canvas.toDataURL('image/jpeg'); var data = canvas.toDataURL('image/jpeg');
var metadata = { var metadata = {
media: { mediaMimeType: 'image/jpeg',
mimeType: 'image/jpeg', modificationTime: new Date(2015, 0, 7, 15, 30, 6),
ifd: { ifd: {
image: { image: {
// Manufacture // Manufacture
271: { 271: {
id: 0x10f, id: 0x10f,
format: 2, format: 2,
componentCount: 12, componentCount: 12,
value: 'Manufacture\0' value: 'Manufacture\0'
},
// Device model
272: {
id: 0x110,
format: 2,
componentCount: 12,
value: 'DeviceModel\0'
},
// GPS Pointer
34853: {
id: 0x8825,
format: 4,
componentCount: 1,
value: 0 // The value is set by the encoder.
}
}, },
exif: { // Device model
// Lens model 272: {
42036: { id: 0x110,
id: 0xa434, format: 2,
format: 2, componentCount: 12,
componentCount: 10, value: 'DeviceModel\0'
value: 'LensModel\0'
}
}, },
gps: { // GPS Pointer
// GPS latitude ref 34853: {
1: { id: 0x8825,
id: 0x1, format: 4,
format: 2, componentCount: 1,
componentCount: 2, value: 0 // The value is set by the encoder.
value: 'N\0' }
} },
exif: {
// Lens model
42036: {
id: 0xa434,
format: 2,
componentCount: 10,
value: 'LensModel\0'
}
},
gps: {
// GPS latitude ref
1: {
id: 0x1,
format: 2,
componentCount: 2,
value: 'N\0'
} }
} }
} }
}; };
var encoder = ImageEncoder.encodeMetadata(metadata, canvas, 1, var encoder = ImageEncoder.encodeMetadata(metadata, canvas, 1);
new Date(2015, 0, 7, 15, 30, 6));
// Assert that ExifEncoder is returned. // Assert that ExifEncoder is returned.
assertTrue(encoder instanceof ExifEncoder); assertTrue(encoder instanceof ExifEncoder);
...@@ -107,6 +105,6 @@ function testExifEncodeAndDecode() { ...@@ -107,6 +105,6 @@ function testExifEncodeAndDecode() {
assertEquals('2015:01:07 15:30:06\0', parsedMetadata.ifd.image[0x132].value); assertEquals('2015:01:07 15:30:06\0', parsedMetadata.ifd.image[0x132].value);
// Thumbnail image // Thumbnail image
assert(parsedMetadata.thumbnailTransform); assertTrue(!!parsedMetadata.thumbnailTransform);
assert(parsedMetadata.thumbnailURL); assertTrue(!!parsedMetadata.thumbnailURL);
} }
...@@ -22,14 +22,15 @@ ImageEncoder.MIN_IMAGE_DIMENSION_FOR_THUMBNAIL = ...@@ -22,14 +22,15 @@ ImageEncoder.MIN_IMAGE_DIMENSION_FOR_THUMBNAIL =
/** /**
* Metadata encoders. * Metadata encoders.
* @type {!Object.<string,function(new:ImageEncoder.MetadataEncoder,!Object)>} * @type {!Object.<string,function(
* new:ImageEncoder.MetadataEncoder,!MetadataItem)>}
* @const * @const
*/ */
ImageEncoder.metadataEncoders = {}; ImageEncoder.metadataEncoders = {};
/** /**
* Registers metadata encoder. * Registers metadata encoder.
* @param {function(new:ImageEncoder.MetadataEncoder,!Object)} constructor * @param {function(new:ImageEncoder.MetadataEncoder,!MetadataItem)} constructor
* Constructor of a metadata encoder. * Constructor of a metadata encoder.
* @param {string} mimeType Mime type of the metadata encoder. * @param {string} mimeType Mime type of the metadata encoder.
*/ */
...@@ -42,12 +43,12 @@ ImageEncoder.registerMetadataEncoder = function(constructor, mimeType) { ...@@ -42,12 +43,12 @@ ImageEncoder.registerMetadataEncoder = function(constructor, mimeType) {
* *
* The encoder will own and modify a copy of the original metadata. * The encoder will own and modify a copy of the original metadata.
* *
* @param {!Object} metadata Original metadata. * @param {!MetadataItem} metadata Original metadata.
* @return {!ImageEncoder.MetadataEncoder} Created metadata encoder. * @return {!ImageEncoder.MetadataEncoder} Created metadata encoder.
*/ */
ImageEncoder.createMetadataEncoder = function(metadata) { ImageEncoder.createMetadataEncoder = function(metadata) {
var constructor = var constructor =
(metadata && ImageEncoder.metadataEncoders[metadata.media.mimeType]) || ImageEncoder.metadataEncoders[metadata.mediaMimeType || ""] ||
ImageEncoder.MetadataEncoder; ImageEncoder.MetadataEncoder;
return new constructor(metadata); return new constructor(metadata);
}; };
...@@ -56,16 +57,14 @@ ImageEncoder.createMetadataEncoder = function(metadata) { ...@@ -56,16 +57,14 @@ ImageEncoder.createMetadataEncoder = function(metadata) {
* Create a metadata encoder object holding a copy of metadata * Create a metadata encoder object holding a copy of metadata
* modified according to the properties of the supplied image. * modified according to the properties of the supplied image.
* *
* @param {!Object} metadata Original metadata. * @param {!MetadataItem} metadata Original metadata.
* @param {!HTMLCanvasElement} canvas Canvas to use for metadata. * @param {!HTMLCanvasElement} canvas Canvas to use for metadata.
* @param {number} thumbnailQuality Encoding quality of a thumbnail. * @param {number} thumbnailQuality Encoding quality of a thumbnail.
* @param {Date=} opt_modificationDateTime Modification date time of an image.
* @return {!ImageEncoder.MetadataEncoder} Encoder with encoded metadata. * @return {!ImageEncoder.MetadataEncoder} Encoder with encoded metadata.
*/ */
ImageEncoder.encodeMetadata = function( ImageEncoder.encodeMetadata = function(metadata, canvas, thumbnailQuality) {
metadata, canvas, thumbnailQuality, opt_modificationDateTime) {
var encoder = ImageEncoder.createMetadataEncoder(metadata); var encoder = ImageEncoder.createMetadataEncoder(metadata);
encoder.setImageData(canvas, opt_modificationDateTime); encoder.setImageData(canvas);
encoder.setThumbnailData(ImageEncoder.createThumbnail(canvas), encoder.setThumbnailData(ImageEncoder.createThumbnail(canvas),
thumbnailQuality); thumbnailQuality);
return encoder; return encoder;
...@@ -82,8 +81,7 @@ ImageEncoder.getBlob = function(canvas, metadataEncoder, imageQuality) { ...@@ -82,8 +81,7 @@ ImageEncoder.getBlob = function(canvas, metadataEncoder, imageQuality) {
ImageUtil.trace.resetTimer('dataurl'); ImageUtil.trace.resetTimer('dataurl');
// WebKit does not support canvas.toBlob yet so canvas.toDataURL is // WebKit does not support canvas.toBlob yet so canvas.toDataURL is
// the only way to use the Chrome built-in image encoder. // the only way to use the Chrome built-in image encoder.
var dataURL = canvas.toDataURL(metadataEncoder.getMetadata().media.mimeType, var dataURL = canvas.toDataURL(metadataEncoder.mimeType, imageQuality);
imageQuality);
ImageUtil.trace.reportTimer('dataurl'); ImageUtil.trace.reportTimer('dataurl');
var encodedImage = ImageEncoder.decodeDataURL(dataURL); var encodedImage = ImageEncoder.decodeDataURL(dataURL);
...@@ -112,8 +110,7 @@ ImageEncoder.getBlob = function(canvas, metadataEncoder, imageQuality) { ...@@ -112,8 +110,7 @@ ImageEncoder.getBlob = function(canvas, metadataEncoder, imageQuality) {
appendSlice(ImageEncoder.stringToArrayBuffer( appendSlice(ImageEncoder.stringToArrayBuffer(
encodedImage, 0, encodedImage.length)); encodedImage, 0, encodedImage.length));
} }
var blob = new Blob(slices, var blob = new Blob(slices, {type: metadataEncoder.mimeType});
{type: metadataEncoder.getMetadata().media.mimeType});
ImageUtil.trace.reportTimer('blob'); ImageUtil.trace.reportTimer('blob');
return blob; return blob;
}; };
...@@ -181,21 +178,34 @@ ImageEncoder.stringToArrayBuffer = function(string, from, to) { ...@@ -181,21 +178,34 @@ ImageEncoder.stringToArrayBuffer = function(string, from, to) {
* Serves as a default metadata encoder for images that none of the metadata * Serves as a default metadata encoder for images that none of the metadata
* parsers recognized. * parsers recognized.
* *
* @param {!Object} original_metadata Starting metadata. * @param {!MetadataItem} originalMetadata Starting metadata.
* @constructor * @constructor
* @struct * @struct
*/ */
ImageEncoder.MetadataEncoder = function(original_metadata) { ImageEncoder.MetadataEncoder = function(originalMetadata) {
this.metadata_ = MetadataCache.cloneMetadata(original_metadata) || {}; var mimeType = ImageEncoder.MetadataEncoder.getMimeType_(originalMetadata);
if (ImageEncoder.MetadataEncoder.getMimeType_(this.metadata_) !==
'image/jpeg') { /**
// Chrome can only encode JPEG and PNG. Force PNG mime type so that we * Chrome can only encode JPEG and PNG. Force PNG mime type so that we
// can save to file and generate a thumbnail. * can save to file and generate a thumbnail.
// TODO(yawano) Change this not to modify metadata. Mime type comes from * @public {string}
// different fields depending on the conditions. Just overriding */
// media.mimeType and use the modified metadata could cause a problem. this.mimeType = mimeType === 'image/jpeg' ? 'image/jpeg' : 'image/png';
this.metadata_.media.mimeType = 'image/png';
} /**
* @protected {string}
*/
this.thumbnailDataUrl = '';
/**
* @protected {number}
*/
this.imageWidth = 0;
/**
* @protected {number}
*/
this.imageHeight = 0;
}; };
/** /**
...@@ -203,41 +213,27 @@ ImageEncoder.MetadataEncoder = function(original_metadata) { ...@@ -203,41 +213,27 @@ ImageEncoder.MetadataEncoder = function(original_metadata) {
* fails, it falls back to external.contentMimeType. If both fields are * fails, it falls back to external.contentMimeType. If both fields are
* undefined, it means that metadata is broken. Then it throws an exception. * undefined, it means that metadata is broken. Then it throws an exception.
* *
* @param {!Object} metadata Metadata. * @param {!MetadataItem} metadata Metadata.
* @return {string} Mime type. * @return {string} Mime type.
* @private * @private
*/ */
ImageEncoder.MetadataEncoder.getMimeType_ = function(metadata) { ImageEncoder.MetadataEncoder.getMimeType_ = function(metadata) {
if (metadata.media.mimeType) if (metadata.mediaMimeType)
return metadata.media.mimeType; return metadata.mediaMimeType;
else if (metadata.external.contentMimeType) else if (metadata.contentMimeType)
return metadata.external.contentMimeType; return metadata.contentMimeType;
assertNotReached(); assertNotReached();
}; };
/**
* Returns metadata.
* @return {!Object} A metadata.
*
* TODO(yawano): MetadataEncoder.getMetadata seems not to be used anymore.
* Investigate this, and remove if possible. Should not modify a metadata by
* using an encoder.
*/
ImageEncoder.MetadataEncoder.prototype.getMetadata = function() {
return this.metadata_;
};
/** /**
* Sets an image data. * Sets an image data.
* @param {!HTMLCanvasElement} canvas Canvas or anything with width and height * @param {!HTMLCanvasElement} canvas Canvas or anything with width and height
* properties. * properties.
* @param {Date=} opt_modificationDateTime Modification date time of an image.
*/ */
ImageEncoder.MetadataEncoder.prototype.setImageData = ImageEncoder.MetadataEncoder.prototype.setImageData = function(canvas) {
function(canvas, opt_modificationDateTime) { this.imageWidth = canvas.width;
this.metadata_.width = canvas.width; this.imageHeight = canvas.height;
this.metadata_.height = canvas.height;
}; };
/** /**
...@@ -247,9 +243,8 @@ ImageEncoder.MetadataEncoder.prototype.setImageData = ...@@ -247,9 +243,8 @@ ImageEncoder.MetadataEncoder.prototype.setImageData =
*/ */
ImageEncoder.MetadataEncoder.prototype.setThumbnailData = ImageEncoder.MetadataEncoder.prototype.setThumbnailData =
function(canvas, quality) { function(canvas, quality) {
this.metadata_.thumbnailURL = this.thumbnailDataUrl =
canvas ? canvas.toDataURL(this.metadata_.media.mimeType, quality) : ''; canvas ? canvas.toDataURL(this.mimeType, quality) : '';
delete this.metadata_.thumbnailTransform;
}; };
/** /**
......
...@@ -31,9 +31,7 @@ function testPngImage(callback) { ...@@ -31,9 +31,7 @@ function testPngImage(callback) {
var canvas = getSampleCanvas(); var canvas = getSampleCanvas();
var metadata = { var metadata = {
media: { mediaMimeType: 'image/png'
mimeType: 'image/png',
}
}; };
reportPromise(encodeAnImageAsDataURL(canvas, metadata, 0.9).then( reportPromise(encodeAnImageAsDataURL(canvas, metadata, 0.9).then(
...@@ -51,9 +49,7 @@ function testJpegImage(callback) { ...@@ -51,9 +49,7 @@ function testJpegImage(callback) {
var canvas = getSampleCanvas(); var canvas = getSampleCanvas();
var metadata = { var metadata = {
media: { mediaMimeType: 'image/jpeg'
mimeType: 'image/jpeg',
}
}; };
reportPromise(encodeAnImageAsDataURL(canvas, metadata, 0.9).then( reportPromise(encodeAnImageAsDataURL(canvas, metadata, 0.9).then(
...@@ -72,9 +68,7 @@ function testWebpImage(callback) { ...@@ -72,9 +68,7 @@ function testWebpImage(callback) {
var canvas = getSampleCanvas(); var canvas = getSampleCanvas();
var metadata = { var metadata = {
media: { mediaMimeType: 'image/webp'
mimeType: 'image/webp'
}
}; };
reportPromise(encodeAnImageAsDataURL(canvas, metadata, 0.9).then( reportPromise(encodeAnImageAsDataURL(canvas, metadata, 0.9).then(
...@@ -90,9 +84,7 @@ function testWithBrokenMetadata() { ...@@ -90,9 +84,7 @@ function testWithBrokenMetadata() {
var canvas = getSampleCanvas(); var canvas = getSampleCanvas();
var metadata = { var metadata = {
media: { // No mimetype field.
// No mimetype field.
}
}; };
// An exception should be thrown if metadata is broken. // An exception should be thrown if metadata is broken.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment